Whamcloud - gitweb
39a8a7ff3d0d8aed545ce6764eb6eaec5c50094c
[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_27Cg() {
2601         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2602         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2603 }
2604 run_test 27Cg "test setstripe with wrong OST idx"
2605
2606 test_27D() {
2607         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2608         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2609         remote_mds_nodsh && skip "remote MDS with nodsh"
2610
2611         local POOL=${POOL:-testpool}
2612         local first_ost=0
2613         local last_ost=$(($OSTCOUNT - 1))
2614         local ost_step=1
2615         local ost_list=$(seq $first_ost $ost_step $last_ost)
2616         local ost_range="$first_ost $last_ost $ost_step"
2617
2618         test_mkdir $DIR/$tdir
2619         pool_add $POOL || error "pool_add failed"
2620         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2621
2622         local skip27D
2623         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2624                 skip27D+="-s 29"
2625         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2626                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2627                         skip27D+=" -s 30,31"
2628         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2629           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2630                 skip27D+=" -s 32,33"
2631         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2632                 skip27D+=" -s 34"
2633         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2634                 error "llapi_layout_test failed"
2635
2636         destroy_test_pools || error "destroy test pools failed"
2637 }
2638 run_test 27D "validate llapi_layout API"
2639
2640 # Verify that default_easize is increased from its initial value after
2641 # accessing a widely striped file.
2642 test_27E() {
2643         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2644         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2645                 skip "client does not have LU-3338 fix"
2646
2647         # 72 bytes is the minimum space required to store striping
2648         # information for a file striped across one OST:
2649         # (sizeof(struct lov_user_md_v3) +
2650         #  sizeof(struct lov_user_ost_data_v1))
2651         local min_easize=72
2652         $LCTL set_param -n llite.*.default_easize $min_easize ||
2653                 error "lctl set_param failed"
2654         local easize=$($LCTL get_param -n llite.*.default_easize)
2655
2656         [ $easize -eq $min_easize ] ||
2657                 error "failed to set default_easize"
2658
2659         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2660                 error "setstripe failed"
2661         # In order to ensure stat() call actually talks to MDS we need to
2662         # do something drastic to this file to shake off all lock, e.g.
2663         # rename it (kills lookup lock forcing cache cleaning)
2664         mv $DIR/$tfile $DIR/${tfile}-1
2665         ls -l $DIR/${tfile}-1
2666         rm $DIR/${tfile}-1
2667
2668         easize=$($LCTL get_param -n llite.*.default_easize)
2669
2670         [ $easize -gt $min_easize ] ||
2671                 error "default_easize not updated"
2672 }
2673 run_test 27E "check that default extended attribute size properly increases"
2674
2675 test_27F() { # LU-5346/LU-7975
2676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2677         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2678         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2679                 skip "Need MDS version at least 2.8.51"
2680         remote_ost_nodsh && skip "remote OST with nodsh"
2681
2682         test_mkdir $DIR/$tdir
2683         rm -f $DIR/$tdir/f0
2684         $LFS setstripe -c 2 $DIR/$tdir
2685
2686         # stop all OSTs to reproduce situation for LU-7975 ticket
2687         for num in $(seq $OSTCOUNT); do
2688                 stop ost$num
2689         done
2690
2691         # open/create f0 with O_LOV_DELAY_CREATE
2692         # truncate f0 to a non-0 size
2693         # close
2694         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2695
2696         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2697         # open/write it again to force delayed layout creation
2698         cat /etc/hosts > $DIR/$tdir/f0 &
2699         catpid=$!
2700
2701         # restart OSTs
2702         for num in $(seq $OSTCOUNT); do
2703                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2704                         error "ost$num failed to start"
2705         done
2706
2707         wait $catpid || error "cat failed"
2708
2709         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2710         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2711                 error "wrong stripecount"
2712
2713 }
2714 run_test 27F "Client resend delayed layout creation with non-zero size"
2715
2716 test_27G() { #LU-10629
2717         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2718                 skip "Need MDS version at least 2.11.51"
2719         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2720         remote_mds_nodsh && skip "remote MDS with nodsh"
2721         local POOL=${POOL:-testpool}
2722         local ostrange="0 0 1"
2723
2724         test_mkdir $DIR/$tdir
2725         touch $DIR/$tdir/$tfile.nopool
2726         pool_add $POOL || error "pool_add failed"
2727         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2728         $LFS setstripe -p $POOL $DIR/$tdir
2729
2730         local pool=$($LFS getstripe -p $DIR/$tdir)
2731
2732         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2733         touch $DIR/$tdir/$tfile.default
2734         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2735         $LFS find $DIR/$tdir -type f --pool $POOL
2736         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2737         [[ "$found" == "2" ]] ||
2738                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2739
2740         $LFS setstripe -d $DIR/$tdir
2741
2742         pool=$($LFS getstripe -p -d $DIR/$tdir)
2743
2744         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2745 }
2746 run_test 27G "Clear OST pool from stripe"
2747
2748 test_27H() {
2749         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2750                 skip "Need MDS version newer than 2.11.54"
2751         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2752         test_mkdir $DIR/$tdir
2753         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2754         touch $DIR/$tdir/$tfile
2755         $LFS getstripe -c $DIR/$tdir/$tfile
2756         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2757                 error "two-stripe file doesn't have two stripes"
2758
2759         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2760         $LFS getstripe -y $DIR/$tdir/$tfile
2761         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2762              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2763                 error "expected l_ost_idx: [02]$ not matched"
2764
2765         # make sure ost list has been cleared
2766         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2767         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2768                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2769         touch $DIR/$tdir/f3
2770         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2771 }
2772 run_test 27H "Set specific OSTs stripe"
2773
2774 test_27I() {
2775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2777         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2778                 skip "Need MDS version newer than 2.12.52"
2779         local pool=$TESTNAME
2780         local ostrange="1 1 1"
2781
2782         save_layout_restore_at_exit $MOUNT
2783         $LFS setstripe -c 2 -i 0 $MOUNT
2784         pool_add $pool || error "pool_add failed"
2785         pool_add_targets $pool $ostrange ||
2786                 error "pool_add_targets failed"
2787         test_mkdir $DIR/$tdir
2788         $LFS setstripe -p $pool $DIR/$tdir
2789         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2790         $LFS getstripe $DIR/$tdir/$tfile
2791 }
2792 run_test 27I "check that root dir striping does not break parent dir one"
2793
2794 test_27J() {
2795         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2796                 skip "Need MDS version newer than 2.12.51"
2797
2798         test_mkdir $DIR/$tdir
2799         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2800         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2801
2802         # create foreign file (raw way)
2803         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2804                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2805
2806         ! $LFS setstripe --foreign --flags foo \
2807                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2808                         error "creating $tfile with '--flags foo' should fail"
2809
2810         ! $LFS setstripe --foreign --flags 0xffffffff \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile w/ 0xffffffff flags should fail"
2813
2814         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2815                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2816
2817         # verify foreign file (raw way)
2818         parse_foreign_file -f $DIR/$tdir/$tfile |
2819                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2821         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2822                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2823         parse_foreign_file -f $DIR/$tdir/$tfile |
2824                 grep "lov_foreign_size: 73" ||
2825                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2826         parse_foreign_file -f $DIR/$tdir/$tfile |
2827                 grep "lov_foreign_type: 1" ||
2828                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2829         parse_foreign_file -f $DIR/$tdir/$tfile |
2830                 grep "lov_foreign_flags: 0x0000DA08" ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2832         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2833                 grep "lov_foreign_value: 0x" |
2834                 sed -e 's/lov_foreign_value: 0x//')
2835         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2836         [[ $lov = ${lov2// /} ]] ||
2837                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2838
2839         # create foreign file (lfs + API)
2840         $LFS setstripe --foreign=none --flags 0xda08 \
2841                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2842                 error "$DIR/$tdir/${tfile}2: create failed"
2843
2844         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2845                 grep "lfm_magic:.*0x0BD70BD0" ||
2846                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2847         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2850         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2851                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2853                 grep "lfm_flags:.*0x0000DA08" ||
2854                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2855         $LFS getstripe $DIR/$tdir/${tfile}2 |
2856                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2857                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2858
2859         # modify striping should fail
2860         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2861                 error "$DIR/$tdir/$tfile: setstripe should fail"
2862         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2863                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2864
2865         # R/W should fail
2866         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2867         cat $DIR/$tdir/${tfile}2 &&
2868                 error "$DIR/$tdir/${tfile}2: read should fail"
2869         cat /etc/passwd > $DIR/$tdir/$tfile &&
2870                 error "$DIR/$tdir/$tfile: write should fail"
2871         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: write should fail"
2873
2874         # chmod should work
2875         chmod 222 $DIR/$tdir/$tfile ||
2876                 error "$DIR/$tdir/$tfile: chmod failed"
2877         chmod 222 $DIR/$tdir/${tfile}2 ||
2878                 error "$DIR/$tdir/${tfile}2: chmod failed"
2879
2880         # chown should work
2881         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2882                 error "$DIR/$tdir/$tfile: chown failed"
2883         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2884                 error "$DIR/$tdir/${tfile}2: chown failed"
2885
2886         # rename should work
2887         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2888                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2889         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2890                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2891
2892         #remove foreign file
2893         rm $DIR/$tdir/${tfile}.new ||
2894                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2895         rm $DIR/$tdir/${tfile}2.new ||
2896                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2897 }
2898 run_test 27J "basic ops on file with foreign LOV"
2899
2900 test_27K() {
2901         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2902                 skip "Need MDS version newer than 2.12.49"
2903
2904         test_mkdir $DIR/$tdir
2905         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2906         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2907
2908         # create foreign dir (raw way)
2909         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2910                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2911
2912         ! $LFS setdirstripe --foreign --flags foo \
2913                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2914                         error "creating $tdir with '--flags foo' should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir w/ 0xffffffff flags should fail"
2919
2920         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2921                 error "create_foreign_dir FAILED"
2922
2923         # verify foreign dir (raw way)
2924         parse_foreign_dir -d $DIR/$tdir/$tdir |
2925                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2926                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2928                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2929         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2930                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir |
2932                 grep "lmv_foreign_flags: 55813$" ||
2933                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2934         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2935                 grep "lmv_foreign_value: 0x" |
2936                 sed 's/lmv_foreign_value: 0x//')
2937         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2938                 sed 's/ //g')
2939         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2940
2941         # create foreign dir (lfs + API)
2942         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2943                 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/$tdir/${tdir}2: create failed"
2945
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2947
2948         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2949                 grep "lfm_magic:.*0x0CD50CD0" ||
2950                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2951         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2952         # - sizeof(lfm_type) - sizeof(lfm_flags)
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2958                 grep "lfm_flags:.*0x0000DA05" ||
2959                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2960         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2961                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2962                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2963
2964         # file create in dir should fail
2965         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2966         touch $DIR/$tdir/${tdir}2/$tfile &&
2967                 error "$DIR/${tdir}2: file create should fail"
2968
2969         # chmod should work
2970         chmod 777 $DIR/$tdir/$tdir ||
2971                 error "$DIR/$tdir: chmod failed"
2972         chmod 777 $DIR/$tdir/${tdir}2 ||
2973                 error "$DIR/${tdir}2: chmod failed"
2974
2975         # chown should work
2976         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2977                 error "$DIR/$tdir: chown failed"
2978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2979                 error "$DIR/${tdir}2: chown failed"
2980
2981         # rename should work
2982         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2983                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2984         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2985                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2986
2987         #remove foreign dir
2988         rmdir $DIR/$tdir/${tdir}.new ||
2989                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2990         rmdir $DIR/$tdir/${tdir}2.new ||
2991                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2992 }
2993 run_test 27K "basic ops on dir with foreign LMV"
2994
2995 test_27L() {
2996         remote_mds_nodsh && skip "remote MDS with nodsh"
2997
2998         local POOL=${POOL:-$TESTNAME}
2999
3000         pool_add $POOL || error "pool_add failed"
3001
3002         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3003                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3004                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3005 }
3006 run_test 27L "lfs pool_list gives correct pool name"
3007
3008 test_27M() {
3009         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3010                 skip "Need MDS version >= than 2.12.57"
3011         remote_mds_nodsh && skip "remote MDS with nodsh"
3012         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3013
3014         # Set default striping on directory
3015         local setcount=4
3016         local stripe_opt
3017         local mdts=$(comma_list $(mdts_nodes))
3018
3019         # if we run against a 2.12 server which lacks overstring support
3020         # then the connect_flag will not report overstriping, even if client
3021         # is 2.14+
3022         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3023                 stripe_opt="-C $setcount"
3024         elif (( $OSTCOUNT >= $setcount )); then
3025                 stripe_opt="-c $setcount"
3026         else
3027                 skip "server does not support overstriping"
3028         fi
3029
3030         test_mkdir $DIR/$tdir
3031
3032         # Validate existing append_* params and ensure restore
3033         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3034         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3035         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3036
3037         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3038         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3039         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3040
3041         $LFS setstripe $stripe_opt $DIR/$tdir
3042
3043         echo 1 > $DIR/$tdir/${tfile}.1
3044         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3045         [ $count -eq $setcount ] ||
3046                 error "(1) stripe count $count, should be $setcount"
3047
3048         local appendcount=$orig_count
3049         echo 1 >> $DIR/$tdir/${tfile}.2_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(2)stripe count $count, should be $appendcount for append"
3053
3054         # Disable O_APPEND striping, verify it works
3055         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3056
3057         # Should now get the default striping, which is 4
3058         setcount=4
3059         echo 1 >> $DIR/$tdir/${tfile}.3_append
3060         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3061         [ $count -eq $setcount ] ||
3062                 error "(3) stripe count $count, should be $setcount"
3063
3064         # Try changing the stripe count for append files
3065         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3066
3067         # Append striping is now 2 (directory default is still 4)
3068         appendcount=2
3069         echo 1 >> $DIR/$tdir/${tfile}.4_append
3070         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(4) stripe count $count, should be $appendcount for append"
3073
3074         # Test append stripe count of -1
3075         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3076         appendcount=$OSTCOUNT
3077         echo 1 >> $DIR/$tdir/${tfile}.5
3078         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3079         [ $count -eq $appendcount ] ||
3080                 error "(5) stripe count $count, should be $appendcount for append"
3081
3082         # Set append striping back to default of 1
3083         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3084
3085         # Try a new default striping, PFL + DOM
3086         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3087
3088         # Create normal DOM file, DOM returns stripe count == 0
3089         setcount=0
3090         touch $DIR/$tdir/${tfile}.6
3091         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3092         [ $count -eq $setcount ] ||
3093                 error "(6) stripe count $count, should be $setcount"
3094
3095         # Show
3096         appendcount=1
3097         echo 1 >> $DIR/$tdir/${tfile}.7_append
3098         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3099         [ $count -eq $appendcount ] ||
3100                 error "(7) stripe count $count, should be $appendcount for append"
3101
3102         # Clean up DOM layout
3103         $LFS setstripe -d $DIR/$tdir
3104
3105         save_layout_restore_at_exit $MOUNT
3106         # Now test that append striping works when layout is from root
3107         $LFS setstripe -c 2 $MOUNT
3108         # Make a special directory for this
3109         mkdir $DIR/${tdir}/${tdir}.2
3110
3111         # Verify for normal file
3112         setcount=2
3113         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3114         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3115         [ $count -eq $setcount ] ||
3116                 error "(8) stripe count $count, should be $setcount"
3117
3118         appendcount=1
3119         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3120         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3121         [ $count -eq $appendcount ] ||
3122                 error "(9) stripe count $count, should be $appendcount for append"
3123
3124         # Now test O_APPEND striping with pools
3125         pool_add $TESTNAME || error "pool creation failed"
3126         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3127         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3128
3129         echo 1 >> $DIR/$tdir/${tfile}.10_append
3130
3131         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3132         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3133
3134         # Check that count is still correct
3135         appendcount=1
3136         echo 1 >> $DIR/$tdir/${tfile}.11_append
3137         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3138         [ $count -eq $appendcount ] ||
3139                 error "(11) stripe count $count, should be $appendcount for append"
3140
3141         # Disable O_APPEND stripe count, verify pool works separately
3142         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3143
3144         echo 1 >> $DIR/$tdir/${tfile}.12_append
3145
3146         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3147         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3148
3149         # Remove pool setting, verify it's not applied
3150         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3151
3152         echo 1 >> $DIR/$tdir/${tfile}.13_append
3153
3154         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3155         [ "$pool" = "" ] || error "(13) pool found: $pool"
3156 }
3157 run_test 27M "test O_APPEND striping"
3158
3159 test_27N() {
3160         combined_mgs_mds && skip "needs separate MGS/MDT"
3161
3162         pool_add $TESTNAME || error "pool_add failed"
3163         do_facet mgs "$LCTL pool_list $FSNAME" |
3164                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3165                 error "lctl pool_list on MGS failed"
3166 }
3167 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3168
3169 clean_foreign_symlink() {
3170         trap 0
3171         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3172         for i in $DIR/$tdir/* ; do
3173                 $LFS unlink_foreign $i || true
3174         done
3175 }
3176
3177 test_27O() {
3178         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3179                 skip "Need MDS version newer than 2.12.51"
3180
3181         test_mkdir $DIR/$tdir
3182         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3183         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3184
3185         trap clean_foreign_symlink EXIT
3186
3187         # enable foreign_symlink behaviour
3188         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3189
3190         # foreign symlink LOV format is a partial path by default
3191
3192         # create foreign file (lfs + API)
3193         $LFS setstripe --foreign=symlink --flags 0xda05 \
3194                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3195                 error "$DIR/$tdir/${tfile}: create failed"
3196
3197         $LFS getstripe -v $DIR/$tdir/${tfile} |
3198                 grep "lfm_magic:.*0x0BD70BD0" ||
3199                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3200         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3201                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3202         $LFS getstripe -v $DIR/$tdir/${tfile} |
3203                 grep "lfm_flags:.*0x0000DA05" ||
3204                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3205         $LFS getstripe $DIR/$tdir/${tfile} |
3206                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3207                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3208
3209         # modify striping should fail
3210         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3211                 error "$DIR/$tdir/$tfile: setstripe should fail"
3212
3213         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3214         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3215         cat /etc/passwd > $DIR/$tdir/$tfile &&
3216                 error "$DIR/$tdir/$tfile: write should fail"
3217
3218         # rename should succeed
3219         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3220                 error "$DIR/$tdir/$tfile: rename has failed"
3221
3222         #remove foreign_symlink file should fail
3223         rm $DIR/$tdir/${tfile}.new &&
3224                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3225
3226         #test fake symlink
3227         mkdir /tmp/${uuid1} ||
3228                 error "/tmp/${uuid1}: mkdir has failed"
3229         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3230                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3231         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3232         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3233                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3234         #read should succeed now
3235         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3236                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3237         #write should succeed now
3238         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3239                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3240         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3241                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3242         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3243                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3244
3245         #check that getstripe still works
3246         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3247                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3248
3249         # chmod should still succeed
3250         chmod 644 $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3252
3253         # chown should still succeed
3254         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3255                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3256
3257         # rename should still succeed
3258         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3259                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3260
3261         #remove foreign_symlink file should still fail
3262         rm $DIR/$tdir/${tfile} &&
3263                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3264
3265         #use special ioctl() to unlink foreign_symlink file
3266         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3267                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3268
3269 }
3270 run_test 27O "basic ops on foreign file of symlink type"
3271
3272 test_27P() {
3273         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3274                 skip "Need MDS version newer than 2.12.49"
3275
3276         test_mkdir $DIR/$tdir
3277         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3278         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3279
3280         trap clean_foreign_symlink EXIT
3281
3282         # enable foreign_symlink behaviour
3283         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3284
3285         # foreign symlink LMV format is a partial path by default
3286
3287         # create foreign dir (lfs + API)
3288         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3289                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3290                 error "$DIR/$tdir/${tdir}: create failed"
3291
3292         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3293
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3295                 grep "lfm_magic:.*0x0CD50CD0" ||
3296                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3297         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3299         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3300                 grep "lfm_flags:.*0x0000DA05" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3302         $LFS getdirstripe $DIR/$tdir/${tdir} |
3303                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3304                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3305
3306         # file create in dir should fail
3307         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3308         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3309
3310         # rename should succeed
3311         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3312                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should fail
3315         rmdir $DIR/$tdir/${tdir}.new &&
3316                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3317
3318         #test fake symlink
3319         mkdir -p /tmp/${uuid1}/${uuid2} ||
3320                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3321         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3322                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3323         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3324         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3325                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3326         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3327                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3328
3329         #check that getstripe fails now that foreign_symlink enabled
3330         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3331                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3332
3333         # file create in dir should work now
3334         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3335                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3336         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3337                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3338         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3339                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3340
3341         # chmod should still succeed
3342         chmod 755 $DIR/$tdir/${tdir}.new ||
3343                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3344
3345         # chown should still succeed
3346         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3347                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3348
3349         # rename should still succeed
3350         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3351                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3352
3353         #remove foreign_symlink dir should still fail
3354         rmdir $DIR/$tdir/${tdir} &&
3355                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3356
3357         #use special ioctl() to unlink foreign_symlink file
3358         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3359                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3360
3361         #created file should still exist
3362         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3363                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3364         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3365                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3366 }
3367 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3368
3369 test_27Q() {
3370         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3371         stack_trap "rm -f $TMP/$tfile*"
3372
3373         test_mkdir $DIR/$tdir-1
3374         test_mkdir $DIR/$tdir-2
3375
3376         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3377         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3378
3379         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3380         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3381
3382         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3383         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3384
3385         # Create some bad symlinks and ensure that we don't loop
3386         # forever or something. These should return ELOOP (40) and
3387         # ENOENT (2) but I don't want to test for that because there's
3388         # always some weirdo architecture that needs to ruin
3389         # everything by defining these error numbers differently.
3390
3391         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3392         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3393
3394         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3395         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3396
3397         return 0
3398 }
3399 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3400
3401 test_27R() {
3402         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3403                 skip "need MDS 2.14.55 or later"
3404         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3405
3406         local testdir="$DIR/$tdir"
3407         test_mkdir -p $testdir
3408         stack_trap "rm -rf $testdir"
3409         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3410
3411         local f1="$testdir/f1"
3412         touch $f1 || error "failed to touch $f1"
3413         local count=$($LFS getstripe -c $f1)
3414         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3415
3416         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3417         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3418
3419         local maxcount=$(($OSTCOUNT - 1))
3420         local mdts=$(comma_list $(mdts_nodes))
3421         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3422         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3423
3424         local f2="$testdir/f2"
3425         touch $f2 || error "failed to touch $f2"
3426         local count=$($LFS getstripe -c $f2)
3427         (( $count == $maxcount )) || error "wrong stripe count"
3428 }
3429 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3430
3431 test_27T() {
3432         [ $(facet_host client) == $(facet_host ost1) ] &&
3433                 skip "need ost1 and client on different nodes"
3434
3435 #define OBD_FAIL_OSC_NO_GRANT            0x411
3436         $LCTL set_param fail_loc=0x20000411 fail_val=1
3437 #define OBD_FAIL_OST_ENOSPC              0x215
3438         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3439         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3440         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3441                 error "multiop failed"
3442 }
3443 run_test 27T "no eio on close on partial write due to enosp"
3444
3445 test_27U() {
3446         local dir=$DIR/$tdir
3447         local file=$dir/$tfile
3448         local append_pool=${TESTNAME}-append
3449         local normal_pool=${TESTNAME}-normal
3450         local pool
3451         local stripe_count
3452         local stripe_count2
3453         local mdts=$(comma_list $(mdts_nodes))
3454
3455         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3456                 skip "Need MDS version at least 2.15.51 for append pool feature"
3457
3458         # Validate existing append_* params and ensure restore
3459         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3460         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3461         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3462
3463         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3464         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3465         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3466
3467         pool_add $append_pool || error "pool creation failed"
3468         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3469
3470         pool_add $normal_pool || error "pool creation failed"
3471         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3472
3473         test_mkdir $dir
3474         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3475
3476         echo XXX >> $file.1
3477         $LFS getstripe $file.1
3478
3479         pool=$($LFS getstripe -p $file.1)
3480         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3481
3482         stripe_count2=$($LFS getstripe -c $file.1)
3483         ((stripe_count2 == stripe_count)) ||
3484                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3485
3486         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3487
3488         echo XXX >> $file.2
3489         $LFS getstripe $file.2
3490
3491         pool=$($LFS getstripe -p $file.2)
3492         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3493
3494         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3495
3496         echo XXX >> $file.3
3497         $LFS getstripe $file.3
3498
3499         stripe_count2=$($LFS getstripe -c $file.3)
3500         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3501 }
3502 run_test 27U "append pool and stripe count work with composite default layout"
3503
3504 # createtest also checks that device nodes are created and
3505 # then visible correctly (#2091)
3506 test_28() { # bug 2091
3507         test_mkdir $DIR/d28
3508         $CREATETEST $DIR/d28/ct || error "createtest failed"
3509 }
3510 run_test 28 "create/mknod/mkdir with bad file types ============"
3511
3512 test_29() {
3513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3514
3515         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3516                 disable_opencache
3517                 stack_trap "restore_opencache"
3518         }
3519
3520         sync; sleep 1; sync # flush out any dirty pages from previous tests
3521         cancel_lru_locks
3522         test_mkdir $DIR/d29
3523         touch $DIR/d29/foo
3524         log 'first d29'
3525         ls -l $DIR/d29
3526
3527         declare -i LOCKCOUNTORIG=0
3528         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3529                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3530         done
3531         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3532
3533         declare -i LOCKUNUSEDCOUNTORIG=0
3534         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3535                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3536         done
3537
3538         log 'second d29'
3539         ls -l $DIR/d29
3540         log 'done'
3541
3542         declare -i LOCKCOUNTCURRENT=0
3543         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3544                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3545         done
3546
3547         declare -i LOCKUNUSEDCOUNTCURRENT=0
3548         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3549                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3550         done
3551
3552         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3553                 $LCTL set_param -n ldlm.dump_namespaces ""
3554                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3555                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3556                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3557                 return 2
3558         fi
3559         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3560                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3561                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3562                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3563                 return 3
3564         fi
3565 }
3566 run_test 29 "IT_GETATTR regression  ============================"
3567
3568 test_30a() { # was test_30
3569         cp $(which ls) $DIR || cp /bin/ls $DIR
3570         $DIR/ls / || error "Can't execute binary from lustre"
3571         rm $DIR/ls
3572 }
3573 run_test 30a "execute binary from Lustre (execve) =============="
3574
3575 test_30b() {
3576         cp `which ls` $DIR || cp /bin/ls $DIR
3577         chmod go+rx $DIR/ls
3578         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3579         rm $DIR/ls
3580 }
3581 run_test 30b "execute binary from Lustre as non-root ==========="
3582
3583 test_30c() { # b=22376
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         cp $(which ls) $DIR || cp /bin/ls $DIR
3587         chmod a-rw $DIR/ls
3588         cancel_lru_locks mdc
3589         cancel_lru_locks osc
3590         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3591         rm -f $DIR/ls
3592 }
3593 run_test 30c "execute binary from Lustre without read perms ===="
3594
3595 test_30d() {
3596         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3597
3598         for i in {1..10}; do
3599                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3600                 local PID=$!
3601                 sleep 1
3602                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3603                 wait $PID || error "executing dd from Lustre failed"
3604                 rm -f $DIR/$tfile
3605         done
3606
3607         rm -f $DIR/dd
3608 }
3609 run_test 30d "execute binary from Lustre while clear locks"
3610
3611 test_31a() {
3612         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3613         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3614 }
3615 run_test 31a "open-unlink file =================================="
3616
3617 test_31b() {
3618         touch $DIR/f31 || error "touch $DIR/f31 failed"
3619         ln $DIR/f31 $DIR/f31b || error "ln failed"
3620         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3621         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3622 }
3623 run_test 31b "unlink file with multiple links while open ======="
3624
3625 test_31c() {
3626         touch $DIR/f31 || error "touch $DIR/f31 failed"
3627         ln $DIR/f31 $DIR/f31c || error "ln failed"
3628         multiop_bg_pause $DIR/f31 O_uc ||
3629                 error "multiop_bg_pause for $DIR/f31 failed"
3630         MULTIPID=$!
3631         $MULTIOP $DIR/f31c Ouc
3632         kill -USR1 $MULTIPID
3633         wait $MULTIPID
3634 }
3635 run_test 31c "open-unlink file with multiple links ============="
3636
3637 test_31d() {
3638         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3639         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3640 }
3641 run_test 31d "remove of open directory ========================="
3642
3643 test_31e() { # bug 2904
3644         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3645 }
3646 run_test 31e "remove of open non-empty directory ==============="
3647
3648 test_31f() { # bug 4554
3649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3650
3651         set -vx
3652         test_mkdir $DIR/d31f
3653         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3654         cp /etc/hosts $DIR/d31f
3655         ls -l $DIR/d31f
3656         $LFS getstripe $DIR/d31f/hosts
3657         multiop_bg_pause $DIR/d31f D_c || return 1
3658         MULTIPID=$!
3659
3660         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3661         test_mkdir $DIR/d31f
3662         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3663         cp /etc/hosts $DIR/d31f
3664         ls -l $DIR/d31f
3665         $LFS getstripe $DIR/d31f/hosts
3666         multiop_bg_pause $DIR/d31f D_c || return 1
3667         MULTIPID2=$!
3668
3669         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3670         wait $MULTIPID || error "first opendir $MULTIPID failed"
3671
3672         sleep 6
3673
3674         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3675         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3676         set +vx
3677 }
3678 run_test 31f "remove of open directory with open-unlink file ==="
3679
3680 test_31g() {
3681         echo "-- cross directory link --"
3682         test_mkdir -c1 $DIR/${tdir}ga
3683         test_mkdir -c1 $DIR/${tdir}gb
3684         touch $DIR/${tdir}ga/f
3685         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3686         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3687         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3688         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3689         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3690 }
3691 run_test 31g "cross directory link==============="
3692
3693 test_31h() {
3694         echo "-- cross directory link --"
3695         test_mkdir -c1 $DIR/${tdir}
3696         test_mkdir -c1 $DIR/${tdir}/dir
3697         touch $DIR/${tdir}/f
3698         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3699         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3700         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3701         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3702         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3703 }
3704 run_test 31h "cross directory link under child==============="
3705
3706 test_31i() {
3707         echo "-- cross directory link --"
3708         test_mkdir -c1 $DIR/$tdir
3709         test_mkdir -c1 $DIR/$tdir/dir
3710         touch $DIR/$tdir/dir/f
3711         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3712         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3713         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3714         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3715         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3716 }
3717 run_test 31i "cross directory link under parent==============="
3718
3719 test_31j() {
3720         test_mkdir -c1 -p $DIR/$tdir
3721         test_mkdir -c1 -p $DIR/$tdir/dir1
3722         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3723         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3724         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3725         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3726         return 0
3727 }
3728 run_test 31j "link for directory==============="
3729
3730 test_31k() {
3731         test_mkdir -c1 -p $DIR/$tdir
3732         touch $DIR/$tdir/s
3733         touch $DIR/$tdir/exist
3734         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3735         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3736         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3737         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3738         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3739         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3740         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3741         return 0
3742 }
3743 run_test 31k "link to file: the same, non-existing, dir==============="
3744
3745 test_31l() {
3746         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3747
3748         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3749         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3750                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3751
3752         touch $DIR/$tfile || error "create failed"
3753         mkdir $DIR/$tdir || error "mkdir failed"
3754         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3755 }
3756 run_test 31l "link to file: target dir has trailing slash"
3757
3758 test_31m() {
3759         mkdir $DIR/d31m
3760         touch $DIR/d31m/s
3761         mkdir $DIR/d31m2
3762         touch $DIR/d31m2/exist
3763         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3764         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3765         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3766         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3767         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3768         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3769         return 0
3770 }
3771 run_test 31m "link to file: the same, non-existing, dir==============="
3772
3773 test_31n() {
3774         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3775         nlink=$(stat --format=%h $DIR/$tfile)
3776         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3777         local fd=$(free_fd)
3778         local cmd="exec $fd<$DIR/$tfile"
3779         eval $cmd
3780         cmd="exec $fd<&-"
3781         trap "eval $cmd" EXIT
3782         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3783         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3784         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3785         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3786         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3787         eval $cmd
3788 }
3789 run_test 31n "check link count of unlinked file"
3790
3791 link_one() {
3792         local tempfile=$(mktemp $1_XXXXXX)
3793         mlink $tempfile $1 2> /dev/null &&
3794                 echo "$BASHPID: link $tempfile to $1 succeeded"
3795         munlink $tempfile
3796 }
3797
3798 test_31o() { # LU-2901
3799         test_mkdir $DIR/$tdir
3800         for LOOP in $(seq 100); do
3801                 rm -f $DIR/$tdir/$tfile*
3802                 for THREAD in $(seq 8); do
3803                         link_one $DIR/$tdir/$tfile.$LOOP &
3804                 done
3805                 wait
3806                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3807                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3808                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3809                         break || true
3810         done
3811 }
3812 run_test 31o "duplicate hard links with same filename"
3813
3814 test_31p() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816
3817         test_mkdir $DIR/$tdir
3818         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3819         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3820
3821         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3822                 error "open unlink test1 failed"
3823         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3824                 error "open unlink test2 failed"
3825
3826         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3827                 error "test1 still exists"
3828         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3829                 error "test2 still exists"
3830 }
3831 run_test 31p "remove of open striped directory"
3832
3833 test_31q() {
3834         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3835
3836         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3837         index=$($LFS getdirstripe -i $DIR/$tdir)
3838         [ $index -eq 3 ] || error "first stripe index $index != 3"
3839         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3840         [ $index -eq 1 ] || error "second stripe index $index != 1"
3841
3842         # when "-c <stripe_count>" is set, the number of MDTs specified after
3843         # "-i" should equal to the stripe count
3844         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3845 }
3846 run_test 31q "create striped directory on specific MDTs"
3847
3848 #LU-14949
3849 test_31r() {
3850         touch $DIR/$tfile.target
3851         touch $DIR/$tfile.source
3852
3853         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3854         $LCTL set_param fail_loc=0x1419 fail_val=3
3855         cat $DIR/$tfile.target &
3856         CATPID=$!
3857
3858         # Guarantee open is waiting before we get here
3859         sleep 1
3860         mv $DIR/$tfile.source $DIR/$tfile.target
3861
3862         wait $CATPID
3863         RC=$?
3864         if [[ $RC -ne 0 ]]; then
3865                 error "open with cat failed, rc=$RC"
3866         fi
3867 }
3868 run_test 31r "open-rename(replace) race"
3869
3870 cleanup_test32_mount() {
3871         local rc=0
3872         trap 0
3873         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3874         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3875         losetup -d $loopdev || true
3876         rm -rf $DIR/$tdir
3877         return $rc
3878 }
3879
3880 test_32a() {
3881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3882
3883         echo "== more mountpoints and symlinks ================="
3884         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3885         trap cleanup_test32_mount EXIT
3886         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3887         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3888                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3889         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3890                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3891         cleanup_test32_mount
3892 }
3893 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3894
3895 test_32b() {
3896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3897
3898         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3899         trap cleanup_test32_mount EXIT
3900         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3901         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3902                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3903         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3904                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3905         cleanup_test32_mount
3906 }
3907 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3908
3909 test_32c() {
3910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3911
3912         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3913         trap cleanup_test32_mount EXIT
3914         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3915         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3916                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3917         test_mkdir -p $DIR/$tdir/d2/test_dir
3918         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3919                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3920         cleanup_test32_mount
3921 }
3922 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3923
3924 test_32d() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         test_mkdir -p $DIR/$tdir/d2/test_dir
3933         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3934                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3935         cleanup_test32_mount
3936 }
3937 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3938
3939 test_32e() {
3940         rm -fr $DIR/$tdir
3941         test_mkdir -p $DIR/$tdir/tmp
3942         local tmp_dir=$DIR/$tdir/tmp
3943         ln -s $DIR/$tdir $tmp_dir/symlink11
3944         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3945         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3946         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3947 }
3948 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3949
3950 test_32f() {
3951         rm -fr $DIR/$tdir
3952         test_mkdir -p $DIR/$tdir/tmp
3953         local tmp_dir=$DIR/$tdir/tmp
3954         ln -s $DIR/$tdir $tmp_dir/symlink11
3955         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3956         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3957         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3958 }
3959 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3960
3961 test_32g() {
3962         local tmp_dir=$DIR/$tdir/tmp
3963         test_mkdir -p $tmp_dir
3964         test_mkdir $DIR/${tdir}2
3965         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3966         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3967         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3968         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3969         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3970         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3971 }
3972 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3973
3974 test_32h() {
3975         rm -fr $DIR/$tdir $DIR/${tdir}2
3976         tmp_dir=$DIR/$tdir/tmp
3977         test_mkdir -p $tmp_dir
3978         test_mkdir $DIR/${tdir}2
3979         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3980         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3981         ls $tmp_dir/symlink12 || error "listing symlink12"
3982         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3983 }
3984 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3985
3986 test_32i() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3990         trap cleanup_test32_mount EXIT
3991         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3992         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3993                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3994         touch $DIR/$tdir/test_file
3995         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3996                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3997         cleanup_test32_mount
3998 }
3999 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4000
4001 test_32j() {
4002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4003
4004         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4005         trap cleanup_test32_mount EXIT
4006         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4007         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4008                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4009         touch $DIR/$tdir/test_file
4010         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4011                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4012         cleanup_test32_mount
4013 }
4014 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4015
4016 test_32k() {
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         rm -fr $DIR/$tdir
4020         trap cleanup_test32_mount EXIT
4021         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4022         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4023                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4024         test_mkdir -p $DIR/$tdir/d2
4025         touch $DIR/$tdir/d2/test_file || error "touch failed"
4026         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4027                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4028         cleanup_test32_mount
4029 }
4030 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4031
4032 test_32l() {
4033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4034
4035         rm -fr $DIR/$tdir
4036         trap cleanup_test32_mount EXIT
4037         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4038         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4039                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4040         test_mkdir -p $DIR/$tdir/d2
4041         touch $DIR/$tdir/d2/test_file || error "touch failed"
4042         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4043                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4044         cleanup_test32_mount
4045 }
4046 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4047
4048 test_32m() {
4049         rm -fr $DIR/d32m
4050         test_mkdir -p $DIR/d32m/tmp
4051         TMP_DIR=$DIR/d32m/tmp
4052         ln -s $DIR $TMP_DIR/symlink11
4053         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4054         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4055                 error "symlink11 not a link"
4056         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4057                 error "symlink01 not a link"
4058 }
4059 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4060
4061 test_32n() {
4062         rm -fr $DIR/d32n
4063         test_mkdir -p $DIR/d32n/tmp
4064         TMP_DIR=$DIR/d32n/tmp
4065         ln -s $DIR $TMP_DIR/symlink11
4066         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4067         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4068         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4069 }
4070 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4071
4072 test_32o() {
4073         touch $DIR/$tfile
4074         test_mkdir -p $DIR/d32o/tmp
4075         TMP_DIR=$DIR/d32o/tmp
4076         ln -s $DIR/$tfile $TMP_DIR/symlink12
4077         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4078         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4079                 error "symlink12 not a link"
4080         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4081         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4082                 error "$DIR/d32o/tmp/symlink12 not file type"
4083         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4084                 error "$DIR/d32o/symlink02 not file type"
4085 }
4086 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4087
4088 test_32p() {
4089         log 32p_1
4090         rm -fr $DIR/d32p
4091         log 32p_2
4092         rm -f $DIR/$tfile
4093         log 32p_3
4094         touch $DIR/$tfile
4095         log 32p_4
4096         test_mkdir -p $DIR/d32p/tmp
4097         log 32p_5
4098         TMP_DIR=$DIR/d32p/tmp
4099         log 32p_6
4100         ln -s $DIR/$tfile $TMP_DIR/symlink12
4101         log 32p_7
4102         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4103         log 32p_8
4104         cat $DIR/d32p/tmp/symlink12 ||
4105                 error "Can't open $DIR/d32p/tmp/symlink12"
4106         log 32p_9
4107         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4108         log 32p_10
4109 }
4110 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4111
4112 test_32q() {
4113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4114
4115         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4116         trap cleanup_test32_mount EXIT
4117         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4118         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4119         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4120                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4121         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4122         cleanup_test32_mount
4123 }
4124 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4125
4126 test_32r() {
4127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4128
4129         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4130         trap cleanup_test32_mount EXIT
4131         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4132         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4133         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4134                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4135         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4136         cleanup_test32_mount
4137 }
4138 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4139
4140 test_33aa() {
4141         rm -f $DIR/$tfile
4142         touch $DIR/$tfile
4143         chmod 444 $DIR/$tfile
4144         chown $RUNAS_ID $DIR/$tfile
4145         log 33_1
4146         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4147         log 33_2
4148 }
4149 run_test 33aa "write file with mode 444 (should return error)"
4150
4151 test_33a() {
4152         rm -fr $DIR/$tdir
4153         test_mkdir $DIR/$tdir
4154         chown $RUNAS_ID $DIR/$tdir
4155         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4156                 error "$RUNAS create $tdir/$tfile failed"
4157         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4158                 error "open RDWR" || true
4159 }
4160 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4161
4162 test_33b() {
4163         rm -fr $DIR/$tdir
4164         test_mkdir $DIR/$tdir
4165         chown $RUNAS_ID $DIR/$tdir
4166         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4167 }
4168 run_test 33b "test open file with malformed flags (No panic)"
4169
4170 test_33c() {
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172         remote_ost_nodsh && skip "remote OST with nodsh"
4173
4174         local ostnum
4175         local ostname
4176         local write_bytes
4177         local all_zeros
4178
4179         all_zeros=true
4180         test_mkdir $DIR/$tdir
4181         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4182
4183         sync
4184         for ostnum in $(seq $OSTCOUNT); do
4185                 # test-framework's OST numbering is one-based, while Lustre's
4186                 # is zero-based
4187                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4188                 # check if at least some write_bytes stats are counted
4189                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4190                               obdfilter.$ostname.stats |
4191                               awk '/^write_bytes/ {print $7}' )
4192                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4193                 if (( ${write_bytes:-0} > 0 )); then
4194                         all_zeros=false
4195                         break
4196                 fi
4197         done
4198
4199         $all_zeros || return 0
4200
4201         # Write four bytes
4202         echo foo > $DIR/$tdir/bar
4203         # Really write them
4204         sync
4205
4206         # Total up write_bytes after writing.  We'd better find non-zeros.
4207         for ostnum in $(seq $OSTCOUNT); do
4208                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4209                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4210                               obdfilter/$ostname/stats |
4211                               awk '/^write_bytes/ {print $7}' )
4212                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4213                 if (( ${write_bytes:-0} > 0 )); then
4214                         all_zeros=false
4215                         break
4216                 fi
4217         done
4218
4219         if $all_zeros; then
4220                 for ostnum in $(seq $OSTCOUNT); do
4221                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4222                         echo "Check write_bytes is in obdfilter.*.stats:"
4223                         do_facet ost$ostnum lctl get_param -n \
4224                                 obdfilter.$ostname.stats
4225                 done
4226                 error "OST not keeping write_bytes stats (b=22312)"
4227         fi
4228 }
4229 run_test 33c "test write_bytes stats"
4230
4231 test_33d() {
4232         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4234
4235         local MDTIDX=1
4236         local remote_dir=$DIR/$tdir/remote_dir
4237
4238         test_mkdir $DIR/$tdir
4239         $LFS mkdir -i $MDTIDX $remote_dir ||
4240                 error "create remote directory failed"
4241
4242         touch $remote_dir/$tfile
4243         chmod 444 $remote_dir/$tfile
4244         chown $RUNAS_ID $remote_dir/$tfile
4245
4246         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4247
4248         chown $RUNAS_ID $remote_dir
4249         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4250                                         error "create" || true
4251         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4252                                     error "open RDWR" || true
4253         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4254 }
4255 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4256
4257 test_33e() {
4258         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4259
4260         mkdir $DIR/$tdir
4261
4262         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4263         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4264         mkdir $DIR/$tdir/local_dir
4265
4266         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4267         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4268         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4269
4270         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4271                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4272
4273         rmdir $DIR/$tdir/* || error "rmdir failed"
4274
4275         umask 777
4276         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4277         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4278         mkdir $DIR/$tdir/local_dir
4279
4280         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4281         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4282         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4283
4284         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4285                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4286
4287         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4288
4289         umask 000
4290         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4291         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4292         mkdir $DIR/$tdir/local_dir
4293
4294         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4295         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4296         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4297
4298         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4299                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4300 }
4301 run_test 33e "mkdir and striped directory should have same mode"
4302
4303 cleanup_33f() {
4304         trap 0
4305         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4306 }
4307
4308 test_33f() {
4309         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4310         remote_mds_nodsh && skip "remote MDS with nodsh"
4311
4312         mkdir $DIR/$tdir
4313         chmod go+rwx $DIR/$tdir
4314         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4315         trap cleanup_33f EXIT
4316
4317         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4318                 error "cannot create striped directory"
4319
4320         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4321                 error "cannot create files in striped directory"
4322
4323         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4324                 error "cannot remove files in striped directory"
4325
4326         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4327                 error "cannot remove striped directory"
4328
4329         cleanup_33f
4330 }
4331 run_test 33f "nonroot user can create, access, and remove a striped directory"
4332
4333 test_33g() {
4334         mkdir -p $DIR/$tdir/dir2
4335
4336         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4337         echo $err
4338         [[ $err =~ "exists" ]] || error "Not exists error"
4339 }
4340 run_test 33g "nonroot user create already existing root created file"
4341
4342 sub_33h() {
4343         local hash_type=$1
4344         local count=250
4345
4346         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4347                 error "lfs mkdir -H $hash_type $tdir failed"
4348         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4349
4350         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4351         local index2
4352         local fname
4353
4354         for fname in $DIR/$tdir/$tfile.bak \
4355                      $DIR/$tdir/$tfile.SAV \
4356                      $DIR/$tdir/$tfile.orig \
4357                      $DIR/$tdir/$tfile~; do
4358                 touch $fname || error "touch $fname failed"
4359                 index2=$($LFS getstripe -m $fname)
4360                 (( $index == $index2 )) ||
4361                         error "$fname MDT index mismatch $index != $index2"
4362         done
4363
4364         local failed=0
4365         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4366         local pattern
4367
4368         for pattern in ${patterns[*]}; do
4369                 echo "pattern $pattern"
4370                 fname=$DIR/$tdir/$pattern
4371                 for (( i = 0; i < $count; i++ )); do
4372                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4373                                 error "mktemp $DIR/$tdir/$pattern failed"
4374                         index2=$($LFS getstripe -m $fname)
4375                         (( $index == $index2 )) && continue
4376
4377                         failed=$((failed + 1))
4378                         echo "$fname MDT index mismatch $index != $index2"
4379                 done
4380         done
4381
4382         echo "$failed/$count MDT index mismatches, expect ~2-4"
4383         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4384
4385         local same=0
4386         local expect
4387
4388         # verify that "crush" is still broken with all files on same MDT,
4389         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4390         [[ "$hash_type" == "crush" ]] && expect=$count ||
4391                 expect=$((count / MDSCOUNT))
4392
4393         # crush2 doesn't put all-numeric suffixes on the same MDT,
4394         # filename like $tfile.12345678 should *not* be considered temp
4395         for pattern in ${patterns[*]}; do
4396                 local base=${pattern%%X*}
4397                 local suff=${pattern#$base}
4398
4399                 echo "pattern $pattern"
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4402                         touch $fname || error "touch $fname failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index != $index2 )) && continue
4405
4406                         same=$((same + 1))
4407                 done
4408         done
4409
4410         # the number of "bad" hashes is random, as it depends on the random
4411         # filenames generated by "mktemp".  Allow some margin in the results.
4412         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4413         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4414            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4415                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4416         same=0
4417
4418         # crush2 doesn't put suffixes with special characters on the same MDT
4419         # filename like $tfile.txt.1234 should *not* be considered temp
4420         for pattern in ${patterns[*]}; do
4421                 local base=${pattern%%X*}
4422                 local suff=${pattern#$base}
4423
4424                 pattern=$base...${suff/XXX}
4425                 echo "pattern=$pattern"
4426                 for (( i = 0; i < $count; i++ )); do
4427                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4428                                 error "touch $fname failed"
4429                         index2=$($LFS getstripe -m $fname)
4430                         (( $index != $index2 )) && continue
4431
4432                         same=$((same + 1))
4433                 done
4434         done
4435
4436         # the number of "bad" hashes is random, as it depends on the random
4437         # filenames generated by "mktemp".  Allow some margin in the results.
4438         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4439         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4440            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4441                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4442 }
4443
4444 test_33h() {
4445         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4446         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4447                 skip "Need MDS version at least 2.13.50"
4448
4449         sub_33h crush
4450 }
4451 run_test 33h "temp file is located on the same MDT as target (crush)"
4452
4453 test_33hh() {
4454         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4455         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4456         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4457                 skip "Need MDS version at least 2.15.0 for crush2"
4458
4459         sub_33h crush2
4460 }
4461 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4462
4463 test_33i()
4464 {
4465         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4466
4467         local FNAME=$(str_repeat 'f' 250)
4468
4469         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4470         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4471
4472         local count
4473         local total
4474
4475         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4476
4477         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4478
4479         lctl --device %$MDC deactivate
4480         stack_trap "lctl --device %$MDC activate"
4481         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4482         total=$(\ls -l $DIR/$tdir | wc -l)
4483         # "ls -l" will list total in the first line
4484         total=$((total - 1))
4485         (( total + count == 1000 )) ||
4486                 error "ls list $total files, $count files on MDT1"
4487 }
4488 run_test 33i "striped directory can be accessed when one MDT is down"
4489
4490 test_33j() {
4491         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4492
4493         mkdir -p $DIR/$tdir/
4494
4495         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4496                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4497
4498         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4499                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4500
4501         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4502                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4503
4504         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4505                 error "-D was not specified, but still failed"
4506 }
4507 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4508
4509 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4510 test_34a() {
4511         rm -f $DIR/f34
4512         $MCREATE $DIR/f34 || error "mcreate failed"
4513         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4514                 error "getstripe failed"
4515         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4517                 error "getstripe failed"
4518         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4519                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4520 }
4521 run_test 34a "truncate file that has not been opened ==========="
4522
4523 test_34b() {
4524         [ ! -f $DIR/f34 ] && test_34a
4525         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4526                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4527         $OPENFILE -f O_RDONLY $DIR/f34
4528         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4529                 error "getstripe failed"
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4531                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4532 }
4533 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4534
4535 test_34c() {
4536         [ ! -f $DIR/f34 ] && test_34a
4537         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4538                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4539         $OPENFILE -f O_RDWR $DIR/f34
4540         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4541                 error "$LFS getstripe failed"
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544 }
4545 run_test 34c "O_RDWR opening file-with-size works =============="
4546
4547 test_34d() {
4548         [ ! -f $DIR/f34 ] && test_34a
4549         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4550                 error "dd failed"
4551         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4552                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4553         rm $DIR/f34
4554 }
4555 run_test 34d "write to sparse file ============================="
4556
4557 test_34e() {
4558         rm -f $DIR/f34e
4559         $MCREATE $DIR/f34e || error "mcreate failed"
4560         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4561         $CHECKSTAT -s 1000 $DIR/f34e ||
4562                 error "Size of $DIR/f34e not equal to 1000 bytes"
4563         $OPENFILE -f O_RDWR $DIR/f34e
4564         $CHECKSTAT -s 1000 $DIR/f34e ||
4565                 error "Size of $DIR/f34e not equal to 1000 bytes"
4566 }
4567 run_test 34e "create objects, some with size and some without =="
4568
4569 test_34f() { # bug 6242, 6243
4570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4571
4572         SIZE34F=48000
4573         rm -f $DIR/f34f
4574         $MCREATE $DIR/f34f || error "mcreate failed"
4575         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4576         dd if=$DIR/f34f of=$TMP/f34f
4577         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4578         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4579         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4580         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4581         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4582 }
4583 run_test 34f "read from a file with no objects until EOF ======="
4584
4585 test_34g() {
4586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4587
4588         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4589                 error "dd failed"
4590         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4591         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4592                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4593         cancel_lru_locks osc
4594         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4595                 error "wrong size after lock cancel"
4596
4597         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4598         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4599                 error "expanding truncate failed"
4600         cancel_lru_locks osc
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4602                 error "wrong expanded size after lock cancel"
4603 }
4604 run_test 34g "truncate long file ==============================="
4605
4606 test_34h() {
4607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4608
4609         local gid=10
4610         local sz=1000
4611
4612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4613         sync # Flush the cache so that multiop below does not block on cache
4614              # flush when getting the group lock
4615         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4616         MULTIPID=$!
4617
4618         # Since just timed wait is not good enough, let's do a sync write
4619         # that way we are sure enough time for a roundtrip + processing
4620         # passed + 2 seconds of extra margin.
4621         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4622         rm $DIR/${tfile}-1
4623         sleep 2
4624
4625         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4626                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4627                 kill -9 $MULTIPID
4628         fi
4629         wait $MULTIPID
4630         local nsz=`stat -c %s $DIR/$tfile`
4631         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4632 }
4633 run_test 34h "ftruncate file under grouplock should not block"
4634
4635 test_35a() {
4636         cp /bin/sh $DIR/f35a
4637         chmod 444 $DIR/f35a
4638         chown $RUNAS_ID $DIR/f35a
4639         $RUNAS $DIR/f35a && error || true
4640         rm $DIR/f35a
4641 }
4642 run_test 35a "exec file with mode 444 (should return and not leak)"
4643
4644 test_36a() {
4645         rm -f $DIR/f36
4646         utime $DIR/f36 || error "utime failed for MDS"
4647 }
4648 run_test 36a "MDS utime check (mknod, utime)"
4649
4650 test_36b() {
4651         echo "" > $DIR/f36
4652         utime $DIR/f36 || error "utime failed for OST"
4653 }
4654 run_test 36b "OST utime check (open, utime)"
4655
4656 test_36c() {
4657         rm -f $DIR/d36/f36
4658         test_mkdir $DIR/d36
4659         chown $RUNAS_ID $DIR/d36
4660         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4661 }
4662 run_test 36c "non-root MDS utime check (mknod, utime)"
4663
4664 test_36d() {
4665         [ ! -d $DIR/d36 ] && test_36c
4666         echo "" > $DIR/d36/f36
4667         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4668 }
4669 run_test 36d "non-root OST utime check (open, utime)"
4670
4671 test_36e() {
4672         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4673
4674         test_mkdir $DIR/$tdir
4675         touch $DIR/$tdir/$tfile
4676         $RUNAS utime $DIR/$tdir/$tfile &&
4677                 error "utime worked, expected failure" || true
4678 }
4679 run_test 36e "utime on non-owned file (should return error)"
4680
4681 subr_36fh() {
4682         local fl="$1"
4683         local LANG_SAVE=$LANG
4684         local LC_LANG_SAVE=$LC_LANG
4685         export LANG=C LC_LANG=C # for date language
4686
4687         DATESTR="Dec 20  2000"
4688         test_mkdir $DIR/$tdir
4689         lctl set_param fail_loc=$fl
4690         date; date +%s
4691         cp /etc/hosts $DIR/$tdir/$tfile
4692         sync & # write RPC generated with "current" inode timestamp, but delayed
4693         sleep 1
4694         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4695         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4696         cancel_lru_locks $OSC
4697         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4698         date; date +%s
4699         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4700                 echo "BEFORE: $LS_BEFORE" && \
4701                 echo "AFTER : $LS_AFTER" && \
4702                 echo "WANT  : $DATESTR" && \
4703                 error "$DIR/$tdir/$tfile timestamps changed" || true
4704
4705         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4706 }
4707
4708 test_36f() {
4709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4710
4711         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4712         subr_36fh "0x80000214"
4713 }
4714 run_test 36f "utime on file racing with OST BRW write =========="
4715
4716 test_36g() {
4717         remote_ost_nodsh && skip "remote OST with nodsh"
4718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4719         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4720                 skip "Need MDS version at least 2.12.51"
4721
4722         local fmd_max_age
4723         local fmd
4724         local facet="ost1"
4725         local tgt="obdfilter"
4726
4727         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4728
4729         test_mkdir $DIR/$tdir
4730         fmd_max_age=$(do_facet $facet \
4731                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4732                 head -n 1")
4733
4734         echo "FMD max age: ${fmd_max_age}s"
4735         touch $DIR/$tdir/$tfile
4736         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4737                 gawk '{cnt=cnt+$1}  END{print cnt}')
4738         echo "FMD before: $fmd"
4739         [[ $fmd == 0 ]] &&
4740                 error "FMD wasn't create by touch"
4741         sleep $((fmd_max_age + 12))
4742         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4743                 gawk '{cnt=cnt+$1}  END{print cnt}')
4744         echo "FMD after: $fmd"
4745         [[ $fmd == 0 ]] ||
4746                 error "FMD wasn't expired by ping"
4747 }
4748 run_test 36g "FMD cache expiry ====================="
4749
4750 test_36h() {
4751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4752
4753         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4754         subr_36fh "0x80000227"
4755 }
4756 run_test 36h "utime on file racing with OST BRW write =========="
4757
4758 test_36i() {
4759         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4760
4761         test_mkdir $DIR/$tdir
4762         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4763
4764         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4765         local new_mtime=$((mtime + 200))
4766
4767         #change Modify time of striped dir
4768         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4769                         error "change mtime failed"
4770
4771         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4772
4773         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4774 }
4775 run_test 36i "change mtime on striped directory"
4776
4777 # test_37 - duplicate with tests 32q 32r
4778
4779 test_38() {
4780         local file=$DIR/$tfile
4781         touch $file
4782         openfile -f O_DIRECTORY $file
4783         local RC=$?
4784         local ENOTDIR=20
4785         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4786         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4787 }
4788 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4789
4790 test_39a() { # was test_39
4791         touch $DIR/$tfile
4792         touch $DIR/${tfile}2
4793 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4794 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4795 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4796         sleep 2
4797         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4798         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4799                 echo "mtime"
4800                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4801                 echo "atime"
4802                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4803                 echo "ctime"
4804                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4805                 error "O_TRUNC didn't change timestamps"
4806         fi
4807 }
4808 run_test 39a "mtime changed on create"
4809
4810 test_39b() {
4811         test_mkdir -c1 $DIR/$tdir
4812         cp -p /etc/passwd $DIR/$tdir/fopen
4813         cp -p /etc/passwd $DIR/$tdir/flink
4814         cp -p /etc/passwd $DIR/$tdir/funlink
4815         cp -p /etc/passwd $DIR/$tdir/frename
4816         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4817
4818         sleep 1
4819         echo "aaaaaa" >> $DIR/$tdir/fopen
4820         echo "aaaaaa" >> $DIR/$tdir/flink
4821         echo "aaaaaa" >> $DIR/$tdir/funlink
4822         echo "aaaaaa" >> $DIR/$tdir/frename
4823
4824         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4825         local link_new=`stat -c %Y $DIR/$tdir/flink`
4826         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4827         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4828
4829         cat $DIR/$tdir/fopen > /dev/null
4830         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4831         rm -f $DIR/$tdir/funlink2
4832         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4833
4834         for (( i=0; i < 2; i++ )) ; do
4835                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4836                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4837                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4838                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4839
4840                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4841                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4842                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4843                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4844
4845                 cancel_lru_locks $OSC
4846                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4847         done
4848 }
4849 run_test 39b "mtime change on open, link, unlink, rename  ======"
4850
4851 # this should be set to past
4852 TEST_39_MTIME=`date -d "1 year ago" +%s`
4853
4854 # bug 11063
4855 test_39c() {
4856         touch $DIR1/$tfile
4857         sleep 2
4858         local mtime0=`stat -c %Y $DIR1/$tfile`
4859
4860         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4861         local mtime1=`stat -c %Y $DIR1/$tfile`
4862         [ "$mtime1" = $TEST_39_MTIME ] || \
4863                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4864
4865         local d1=`date +%s`
4866         echo hello >> $DIR1/$tfile
4867         local d2=`date +%s`
4868         local mtime2=`stat -c %Y $DIR1/$tfile`
4869         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4870                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4871
4872         mv $DIR1/$tfile $DIR1/$tfile-1
4873
4874         for (( i=0; i < 2; i++ )) ; do
4875                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4876                 [ "$mtime2" = "$mtime3" ] || \
4877                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4878
4879                 cancel_lru_locks $OSC
4880                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4881         done
4882 }
4883 run_test 39c "mtime change on rename ==========================="
4884
4885 # bug 21114
4886 test_39d() {
4887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4888
4889         touch $DIR1/$tfile
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891
4892         for (( i=0; i < 2; i++ )) ; do
4893                 local mtime=`stat -c %Y $DIR1/$tfile`
4894                 [ $mtime = $TEST_39_MTIME ] || \
4895                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4896
4897                 cancel_lru_locks $OSC
4898                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4899         done
4900 }
4901 run_test 39d "create, utime, stat =============================="
4902
4903 # bug 21114
4904 test_39e() {
4905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4906
4907         touch $DIR1/$tfile
4908         local mtime1=`stat -c %Y $DIR1/$tfile`
4909
4910         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4911
4912         for (( i=0; i < 2; i++ )) ; do
4913                 local mtime2=`stat -c %Y $DIR1/$tfile`
4914                 [ $mtime2 = $TEST_39_MTIME ] || \
4915                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4916
4917                 cancel_lru_locks $OSC
4918                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4919         done
4920 }
4921 run_test 39e "create, stat, utime, stat ========================"
4922
4923 # bug 21114
4924 test_39f() {
4925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4926
4927         touch $DIR1/$tfile
4928         mtime1=`stat -c %Y $DIR1/$tfile`
4929
4930         sleep 2
4931         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4932
4933         for (( i=0; i < 2; i++ )) ; do
4934                 local mtime2=`stat -c %Y $DIR1/$tfile`
4935                 [ $mtime2 = $TEST_39_MTIME ] || \
4936                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4937
4938                 cancel_lru_locks $OSC
4939                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4940         done
4941 }
4942 run_test 39f "create, stat, sleep, utime, stat ================="
4943
4944 # bug 11063
4945 test_39g() {
4946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4947
4948         echo hello >> $DIR1/$tfile
4949         local mtime1=`stat -c %Y $DIR1/$tfile`
4950
4951         sleep 2
4952         chmod o+r $DIR1/$tfile
4953
4954         for (( i=0; i < 2; i++ )) ; do
4955                 local mtime2=`stat -c %Y $DIR1/$tfile`
4956                 [ "$mtime1" = "$mtime2" ] || \
4957                         error "lost mtime: $mtime2, should be $mtime1"
4958
4959                 cancel_lru_locks $OSC
4960                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4961         done
4962 }
4963 run_test 39g "write, chmod, stat ==============================="
4964
4965 # bug 11063
4966 test_39h() {
4967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4968
4969         touch $DIR1/$tfile
4970         sleep 1
4971
4972         local d1=`date`
4973         echo hello >> $DIR1/$tfile
4974         local mtime1=`stat -c %Y $DIR1/$tfile`
4975
4976         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4977         local d2=`date`
4978         if [ "$d1" != "$d2" ]; then
4979                 echo "write and touch not within one second"
4980         else
4981                 for (( i=0; i < 2; i++ )) ; do
4982                         local mtime2=`stat -c %Y $DIR1/$tfile`
4983                         [ "$mtime2" = $TEST_39_MTIME ] || \
4984                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4985
4986                         cancel_lru_locks $OSC
4987                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4988                 done
4989         fi
4990 }
4991 run_test 39h "write, utime within one second, stat ============="
4992
4993 test_39i() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995
4996         touch $DIR1/$tfile
4997         sleep 1
4998
4999         echo hello >> $DIR1/$tfile
5000         local mtime1=`stat -c %Y $DIR1/$tfile`
5001
5002         mv $DIR1/$tfile $DIR1/$tfile-1
5003
5004         for (( i=0; i < 2; i++ )) ; do
5005                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5006
5007                 [ "$mtime1" = "$mtime2" ] || \
5008                         error "lost mtime: $mtime2, should be $mtime1"
5009
5010                 cancel_lru_locks $OSC
5011                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012         done
5013 }
5014 run_test 39i "write, rename, stat =============================="
5015
5016 test_39j() {
5017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5018
5019         start_full_debug_logging
5020         touch $DIR1/$tfile
5021         sleep 1
5022
5023         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5024         lctl set_param fail_loc=0x80000412
5025         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5026                 error "multiop failed"
5027         local multipid=$!
5028         local mtime1=`stat -c %Y $DIR1/$tfile`
5029
5030         mv $DIR1/$tfile $DIR1/$tfile-1
5031
5032         kill -USR1 $multipid
5033         wait $multipid || error "multiop close failed"
5034
5035         for (( i=0; i < 2; i++ )) ; do
5036                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5037                 [ "$mtime1" = "$mtime2" ] ||
5038                         error "mtime is lost on close: $mtime2, " \
5039                               "should be $mtime1"
5040
5041                 cancel_lru_locks
5042                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5043         done
5044         lctl set_param fail_loc=0
5045         stop_full_debug_logging
5046 }
5047 run_test 39j "write, rename, close, stat ======================="
5048
5049 test_39k() {
5050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5051
5052         touch $DIR1/$tfile
5053         sleep 1
5054
5055         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5056         local multipid=$!
5057         local mtime1=`stat -c %Y $DIR1/$tfile`
5058
5059         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5060
5061         kill -USR1 $multipid
5062         wait $multipid || error "multiop close failed"
5063
5064         for (( i=0; i < 2; i++ )) ; do
5065                 local mtime2=`stat -c %Y $DIR1/$tfile`
5066
5067                 [ "$mtime2" = $TEST_39_MTIME ] || \
5068                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5069
5070                 cancel_lru_locks
5071                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5072         done
5073 }
5074 run_test 39k "write, utime, close, stat ========================"
5075
5076 # this should be set to future
5077 TEST_39_ATIME=`date -d "1 year" +%s`
5078
5079 test_39l() {
5080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5081         remote_mds_nodsh && skip "remote MDS with nodsh"
5082
5083         local atime_diff=$(do_facet $SINGLEMDS \
5084                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5085         rm -rf $DIR/$tdir
5086         mkdir_on_mdt0 $DIR/$tdir
5087
5088         # test setting directory atime to future
5089         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5090         local atime=$(stat -c %X $DIR/$tdir)
5091         [ "$atime" = $TEST_39_ATIME ] ||
5092                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5093
5094         # test setting directory atime from future to now
5095         local now=$(date +%s)
5096         touch -a -d @$now $DIR/$tdir
5097
5098         atime=$(stat -c %X $DIR/$tdir)
5099         [ "$atime" -eq "$now"  ] ||
5100                 error "atime is not updated from future: $atime, $now"
5101
5102         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5103         sleep 3
5104
5105         # test setting directory atime when now > dir atime + atime_diff
5106         local d1=$(date +%s)
5107         ls $DIR/$tdir
5108         local d2=$(date +%s)
5109         cancel_lru_locks mdc
5110         atime=$(stat -c %X $DIR/$tdir)
5111         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5112                 error "atime is not updated  : $atime, should be $d2"
5113
5114         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5115         sleep 3
5116
5117         # test not setting directory atime when now < dir atime + atime_diff
5118         ls $DIR/$tdir
5119         cancel_lru_locks mdc
5120         atime=$(stat -c %X $DIR/$tdir)
5121         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5122                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5123
5124         do_facet $SINGLEMDS \
5125                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5126 }
5127 run_test 39l "directory atime update ==========================="
5128
5129 test_39m() {
5130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5131
5132         touch $DIR1/$tfile
5133         sleep 2
5134         local far_past_mtime=$(date -d "May 29 1953" +%s)
5135         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5136
5137         touch -m -d @$far_past_mtime $DIR1/$tfile
5138         touch -a -d @$far_past_atime $DIR1/$tfile
5139
5140         for (( i=0; i < 2; i++ )) ; do
5141                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5142                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5143                         error "atime or mtime set incorrectly"
5144
5145                 cancel_lru_locks $OSC
5146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5147         done
5148 }
5149 run_test 39m "test atime and mtime before 1970"
5150
5151 test_39n() { # LU-3832
5152         remote_mds_nodsh && skip "remote MDS with nodsh"
5153
5154         local atime_diff=$(do_facet $SINGLEMDS \
5155                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5156         local atime0
5157         local atime1
5158         local atime2
5159
5160         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5161
5162         rm -rf $DIR/$tfile
5163         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5164         atime0=$(stat -c %X $DIR/$tfile)
5165
5166         sleep 5
5167         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5168         atime1=$(stat -c %X $DIR/$tfile)
5169
5170         sleep 5
5171         cancel_lru_locks mdc
5172         cancel_lru_locks osc
5173         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5174         atime2=$(stat -c %X $DIR/$tfile)
5175
5176         do_facet $SINGLEMDS \
5177                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5178
5179         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5180         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5181 }
5182 run_test 39n "check that O_NOATIME is honored"
5183
5184 test_39o() {
5185         TESTDIR=$DIR/$tdir/$tfile
5186         [ -e $TESTDIR ] && rm -rf $TESTDIR
5187         mkdir -p $TESTDIR
5188         cd $TESTDIR
5189         links1=2
5190         ls
5191         mkdir a b
5192         ls
5193         links2=$(stat -c %h .)
5194         [ $(($links1 + 2)) != $links2 ] &&
5195                 error "wrong links count $(($links1 + 2)) != $links2"
5196         rmdir b
5197         links3=$(stat -c %h .)
5198         [ $(($links1 + 1)) != $links3 ] &&
5199                 error "wrong links count $links1 != $links3"
5200         return 0
5201 }
5202 run_test 39o "directory cached attributes updated after create"
5203
5204 test_39p() {
5205         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5206
5207         local MDTIDX=1
5208         TESTDIR=$DIR/$tdir/$tdir
5209         [ -e $TESTDIR ] && rm -rf $TESTDIR
5210         test_mkdir -p $TESTDIR
5211         cd $TESTDIR
5212         links1=2
5213         ls
5214         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5215         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5216         ls
5217         links2=$(stat -c %h .)
5218         [ $(($links1 + 2)) != $links2 ] &&
5219                 error "wrong links count $(($links1 + 2)) != $links2"
5220         rmdir remote_dir2
5221         links3=$(stat -c %h .)
5222         [ $(($links1 + 1)) != $links3 ] &&
5223                 error "wrong links count $links1 != $links3"
5224         return 0
5225 }
5226 run_test 39p "remote directory cached attributes updated after create ========"
5227
5228 test_39r() {
5229         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5230                 skip "no atime update on old OST"
5231         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5232                 skip_env "ldiskfs only test"
5233         fi
5234
5235         local saved_adiff
5236         saved_adiff=$(do_facet ost1 \
5237                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5238         stack_trap "do_facet ost1 \
5239                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5240
5241         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5242
5243         $LFS setstripe -i 0 $DIR/$tfile
5244         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5245                 error "can't write initial file"
5246         cancel_lru_locks osc
5247
5248         # exceed atime_diff and access file
5249         sleep 10
5250         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5251                 error "can't udpate atime"
5252
5253         local atime_cli=$(stat -c %X $DIR/$tfile)
5254         echo "client atime: $atime_cli"
5255         # allow atime update to be written to device
5256         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5257         sleep 5
5258
5259         local ostdev=$(ostdevname 1)
5260         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5261         local seq=${fid[3]#0x}
5262         local oid=${fid[1]}
5263         local oid_hex
5264
5265         if [ $seq == 0 ]; then
5266                 oid_hex=${fid[1]}
5267         else
5268                 oid_hex=${fid[2]#0x}
5269         fi
5270         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5271         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5272
5273         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5274         local atime_ost=$(do_facet ost1 "$cmd" |&
5275                           awk -F'[: ]' '/atime:/ { print $4 }')
5276         (( atime_cli == atime_ost )) ||
5277                 error "atime on client $atime_cli != ost $atime_ost"
5278 }
5279 run_test 39r "lazy atime update on OST"
5280
5281 test_39q() { # LU-8041
5282         local testdir=$DIR/$tdir
5283         mkdir -p $testdir
5284         multiop_bg_pause $testdir D_c || error "multiop failed"
5285         local multipid=$!
5286         cancel_lru_locks mdc
5287         kill -USR1 $multipid
5288         local atime=$(stat -c %X $testdir)
5289         [ "$atime" -ne 0 ] || error "atime is zero"
5290 }
5291 run_test 39q "close won't zero out atime"
5292
5293 test_39s() {
5294         local atime0
5295         local atime1
5296         local atime2
5297         local atime3
5298         local atime4
5299
5300         umount_client $MOUNT
5301         mount_client $MOUNT relatime
5302
5303         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5304         atime0=$(stat -c %X $DIR/$tfile)
5305
5306         # First read updates atime
5307         sleep 1
5308         cat $DIR/$tfile >/dev/null
5309         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5310
5311         # Next reads do not update atime
5312         sleep 1
5313         cat $DIR/$tfile >/dev/null
5314         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5315
5316         # If mtime is greater than atime, atime is updated
5317         sleep 1
5318         touch -m $DIR/$tfile # (mtime = now)
5319         sleep 1
5320         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5321         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5322
5323         # Next reads do not update atime
5324         sleep 1
5325         cat $DIR/$tfile >/dev/null
5326         atime4=$(stat -c %X $DIR/$tfile)
5327
5328         # Remount the client to clear 'relatime' option
5329         remount_client $MOUNT
5330
5331         (( atime0 < atime1 )) ||
5332                 error "atime $atime0 should be smaller than $atime1"
5333         (( atime1 == atime2 )) ||
5334                 error "atime $atime1 was updated to $atime2"
5335         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5336         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5337 }
5338 run_test 39s "relatime is supported"
5339
5340 test_40() {
5341         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5342         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5343                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5344         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5345                 error "$tfile is not 4096 bytes in size"
5346 }
5347 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5348
5349 test_41() {
5350         # bug 1553
5351         small_write $DIR/f41 18
5352 }
5353 run_test 41 "test small file write + fstat ====================="
5354
5355 count_ost_writes() {
5356         lctl get_param -n ${OSC}.*.stats |
5357                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5358                         END { printf("%0.0f", writes) }'
5359 }
5360
5361 # decent default
5362 WRITEBACK_SAVE=500
5363 DIRTY_RATIO_SAVE=40
5364 MAX_DIRTY_RATIO=50
5365 BG_DIRTY_RATIO_SAVE=10
5366 MAX_BG_DIRTY_RATIO=25
5367
5368 start_writeback() {
5369         trap 0
5370         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5371         # dirty_ratio, dirty_background_ratio
5372         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5373                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5374                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5375                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5376         else
5377                 # if file not here, we are a 2.4 kernel
5378                 kill -CONT `pidof kupdated`
5379         fi
5380 }
5381
5382 stop_writeback() {
5383         # setup the trap first, so someone cannot exit the test at the
5384         # exact wrong time and mess up a machine
5385         trap start_writeback EXIT
5386         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5387         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5388                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5389                 sysctl -w vm.dirty_writeback_centisecs=0
5390                 sysctl -w vm.dirty_writeback_centisecs=0
5391                 # save and increase /proc/sys/vm/dirty_ratio
5392                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5393                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5394                 # save and increase /proc/sys/vm/dirty_background_ratio
5395                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5396                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5397         else
5398                 # if file not here, we are a 2.4 kernel
5399                 kill -STOP `pidof kupdated`
5400         fi
5401 }
5402
5403 # ensure that all stripes have some grant before we test client-side cache
5404 setup_test42() {
5405         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5406                 dd if=/dev/zero of=$i bs=4k count=1
5407                 rm $i
5408         done
5409 }
5410
5411 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5412 # file truncation, and file removal.
5413 test_42a() {
5414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5415
5416         setup_test42
5417         cancel_lru_locks $OSC
5418         stop_writeback
5419         sync; sleep 1; sync # just to be safe
5420         BEFOREWRITES=`count_ost_writes`
5421         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5422         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5423         AFTERWRITES=`count_ost_writes`
5424         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5425                 error "$BEFOREWRITES < $AFTERWRITES"
5426         start_writeback
5427 }
5428 run_test 42a "ensure that we don't flush on close"
5429
5430 test_42b() {
5431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5432
5433         setup_test42
5434         cancel_lru_locks $OSC
5435         stop_writeback
5436         sync
5437         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5438         BEFOREWRITES=$(count_ost_writes)
5439         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5440         AFTERWRITES=$(count_ost_writes)
5441         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5442                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5443         fi
5444         BEFOREWRITES=$(count_ost_writes)
5445         sync || error "sync: $?"
5446         AFTERWRITES=$(count_ost_writes)
5447         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5448                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5449         fi
5450         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5451         start_writeback
5452         return 0
5453 }
5454 run_test 42b "test destroy of file with cached dirty data ======"
5455
5456 # if these tests just want to test the effect of truncation,
5457 # they have to be very careful.  consider:
5458 # - the first open gets a {0,EOF}PR lock
5459 # - the first write conflicts and gets a {0, count-1}PW
5460 # - the rest of the writes are under {count,EOF}PW
5461 # - the open for truncate tries to match a {0,EOF}PR
5462 #   for the filesize and cancels the PWs.
5463 # any number of fixes (don't get {0,EOF} on open, match
5464 # composite locks, do smarter file size management) fix
5465 # this, but for now we want these tests to verify that
5466 # the cancellation with truncate intent works, so we
5467 # start the file with a full-file pw lock to match against
5468 # until the truncate.
5469 trunc_test() {
5470         test=$1
5471         file=$DIR/$test
5472         offset=$2
5473         cancel_lru_locks $OSC
5474         stop_writeback
5475         # prime the file with 0,EOF PW to match
5476         touch $file
5477         $TRUNCATE $file 0
5478         sync; sync
5479         # now the real test..
5480         dd if=/dev/zero of=$file bs=1024 count=100
5481         BEFOREWRITES=`count_ost_writes`
5482         $TRUNCATE $file $offset
5483         cancel_lru_locks $OSC
5484         AFTERWRITES=`count_ost_writes`
5485         start_writeback
5486 }
5487
5488 test_42c() {
5489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5490
5491         trunc_test 42c 1024
5492         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5493                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5494         rm $file
5495 }
5496 run_test 42c "test partial truncate of file with cached dirty data"
5497
5498 test_42d() {
5499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5500
5501         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5502         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5503         $LCTL set_param debug=+cache
5504
5505         trunc_test 42d 0
5506         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5507                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5508         rm $file
5509 }
5510 run_test 42d "test complete truncate of file with cached dirty data"
5511
5512 test_42e() { # bug22074
5513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5514
5515         local TDIR=$DIR/${tdir}e
5516         local pages=16 # hardcoded 16 pages, don't change it.
5517         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5518         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5519         local max_dirty_mb
5520         local warmup_files
5521
5522         test_mkdir $DIR/${tdir}e
5523         $LFS setstripe -c 1 $TDIR
5524         createmany -o $TDIR/f $files
5525
5526         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5527
5528         # we assume that with $OSTCOUNT files, at least one of them will
5529         # be allocated on OST0.
5530         warmup_files=$((OSTCOUNT * max_dirty_mb))
5531         createmany -o $TDIR/w $warmup_files
5532
5533         # write a large amount of data into one file and sync, to get good
5534         # avail_grant number from OST.
5535         for ((i=0; i<$warmup_files; i++)); do
5536                 idx=$($LFS getstripe -i $TDIR/w$i)
5537                 [ $idx -ne 0 ] && continue
5538                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5539                 break
5540         done
5541         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5542         sync
5543         $LCTL get_param $proc_osc0/cur_dirty_bytes
5544         $LCTL get_param $proc_osc0/cur_grant_bytes
5545
5546         # create as much dirty pages as we can while not to trigger the actual
5547         # RPCs directly. but depends on the env, VFS may trigger flush during this
5548         # period, hopefully we are good.
5549         for ((i=0; i<$warmup_files; i++)); do
5550                 idx=$($LFS getstripe -i $TDIR/w$i)
5551                 [ $idx -ne 0 ] && continue
5552                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5553         done
5554         $LCTL get_param $proc_osc0/cur_dirty_bytes
5555         $LCTL get_param $proc_osc0/cur_grant_bytes
5556
5557         # perform the real test
5558         $LCTL set_param $proc_osc0/rpc_stats 0
5559         for ((;i<$files; i++)); do
5560                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5561                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5562         done
5563         sync
5564         $LCTL get_param $proc_osc0/rpc_stats
5565
5566         local percent=0
5567         local have_ppr=false
5568         $LCTL get_param $proc_osc0/rpc_stats |
5569                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5570                         # skip lines until we are at the RPC histogram data
5571                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5572                         $have_ppr || continue
5573
5574                         # we only want the percent stat for < 16 pages
5575                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5576
5577                         percent=$((percent + WPCT))
5578                         if [[ $percent -gt 15 ]]; then
5579                                 error "less than 16-pages write RPCs" \
5580                                       "$percent% > 15%"
5581                                 break
5582                         fi
5583                 done
5584         rm -rf $TDIR
5585 }
5586 run_test 42e "verify sub-RPC writes are not done synchronously"
5587
5588 test_43A() { # was test_43
5589         test_mkdir $DIR/$tdir
5590         cp -p /bin/ls $DIR/$tdir/$tfile
5591         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5592         pid=$!
5593         # give multiop a chance to open
5594         sleep 1
5595
5596         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5597         kill -USR1 $pid
5598         # Wait for multiop to exit
5599         wait $pid
5600 }
5601 run_test 43A "execution of file opened for write should return -ETXTBSY"
5602
5603 test_43a() {
5604         test_mkdir $DIR/$tdir
5605         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5606         $DIR/$tdir/sleep 60 &
5607         SLEEP_PID=$!
5608         # Make sure exec of $tdir/sleep wins race with truncate
5609         sleep 1
5610         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5611         kill $SLEEP_PID
5612 }
5613 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5614
5615 test_43b() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617
5618         test_mkdir $DIR/$tdir
5619         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5620         $DIR/$tdir/sleep 60 &
5621         SLEEP_PID=$!
5622         # Make sure exec of $tdir/sleep wins race with truncate
5623         sleep 1
5624         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5625         kill $SLEEP_PID
5626 }
5627 run_test 43b "truncate of file being executed should return -ETXTBSY"
5628
5629 test_43c() {
5630         local testdir="$DIR/$tdir"
5631         test_mkdir $testdir
5632         cp $SHELL $testdir/
5633         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5634                 ( cd $testdir && md5sum -c )
5635 }
5636 run_test 43c "md5sum of copy into lustre"
5637
5638 test_44A() { # was test_44
5639         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5640
5641         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5642         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5643 }
5644 run_test 44A "zero length read from a sparse stripe"
5645
5646 test_44a() {
5647         local nstripe=$($LFS getstripe -c -d $DIR)
5648         [ -z "$nstripe" ] && skip "can't get stripe info"
5649         [[ $nstripe -gt $OSTCOUNT ]] &&
5650                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5651
5652         local stride=$($LFS getstripe -S -d $DIR)
5653         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5654                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5655         fi
5656
5657         OFFSETS="0 $((stride/2)) $((stride-1))"
5658         for offset in $OFFSETS; do
5659                 for i in $(seq 0 $((nstripe-1))); do
5660                         local GLOBALOFFSETS=""
5661                         # size in Bytes
5662                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5663                         local myfn=$DIR/d44a-$size
5664                         echo "--------writing $myfn at $size"
5665                         ll_sparseness_write $myfn $size ||
5666                                 error "ll_sparseness_write"
5667                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5668                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5669                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5670
5671                         for j in $(seq 0 $((nstripe-1))); do
5672                                 # size in Bytes
5673                                 size=$((((j + $nstripe )*$stride + $offset)))
5674                                 ll_sparseness_write $myfn $size ||
5675                                         error "ll_sparseness_write"
5676                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5677                         done
5678                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5679                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5680                         rm -f $myfn
5681                 done
5682         done
5683 }
5684 run_test 44a "test sparse pwrite ==============================="
5685
5686 dirty_osc_total() {
5687         tot=0
5688         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5689                 tot=$(($tot + $d))
5690         done
5691         echo $tot
5692 }
5693 do_dirty_record() {
5694         before=`dirty_osc_total`
5695         echo executing "\"$*\""
5696         eval $*
5697         after=`dirty_osc_total`
5698         echo before $before, after $after
5699 }
5700 test_45() {
5701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5702
5703         f="$DIR/f45"
5704         # Obtain grants from OST if it supports it
5705         echo blah > ${f}_grant
5706         stop_writeback
5707         sync
5708         do_dirty_record "echo blah > $f"
5709         [[ $before -eq $after ]] && error "write wasn't cached"
5710         do_dirty_record "> $f"
5711         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5712         do_dirty_record "echo blah > $f"
5713         [[ $before -eq $after ]] && error "write wasn't cached"
5714         do_dirty_record "sync"
5715         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5716         do_dirty_record "echo blah > $f"
5717         [[ $before -eq $after ]] && error "write wasn't cached"
5718         do_dirty_record "cancel_lru_locks osc"
5719         [[ $before -gt $after ]] ||
5720                 error "lock cancellation didn't lower dirty count"
5721         start_writeback
5722 }
5723 run_test 45 "osc io page accounting ============================"
5724
5725 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5726 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5727 # objects offset and an assert hit when an rpc was built with 1023's mapped
5728 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5729 test_46() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731
5732         f="$DIR/f46"
5733         stop_writeback
5734         sync
5735         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5736         sync
5737         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5738         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5739         sync
5740         start_writeback
5741 }
5742 run_test 46 "dirtying a previously written page ================"
5743
5744 # test_47 is removed "Device nodes check" is moved to test_28
5745
5746 test_48a() { # bug 2399
5747         [ "$mds1_FSTYPE" = "zfs" ] &&
5748         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5749                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5750
5751         test_mkdir $DIR/$tdir
5752         cd $DIR/$tdir
5753         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5754         test_mkdir $DIR/$tdir
5755         touch foo || error "'touch foo' failed after recreating cwd"
5756         test_mkdir bar
5757         touch .foo || error "'touch .foo' failed after recreating cwd"
5758         test_mkdir .bar
5759         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5760         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5761         cd . || error "'cd .' failed after recreating cwd"
5762         mkdir . && error "'mkdir .' worked after recreating cwd"
5763         rmdir . && error "'rmdir .' worked after recreating cwd"
5764         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5765         cd .. || error "'cd ..' failed after recreating cwd"
5766 }
5767 run_test 48a "Access renamed working dir (should return errors)="
5768
5769 test_48b() { # bug 2399
5770         rm -rf $DIR/$tdir
5771         test_mkdir $DIR/$tdir
5772         cd $DIR/$tdir
5773         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5774         touch foo && error "'touch foo' worked after removing cwd"
5775         mkdir foo && error "'mkdir foo' worked after removing cwd"
5776         touch .foo && error "'touch .foo' worked after removing cwd"
5777         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5778         ls . > /dev/null && error "'ls .' worked after removing cwd"
5779         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5780         mkdir . && error "'mkdir .' worked after removing cwd"
5781         rmdir . && error "'rmdir .' worked after removing cwd"
5782         ln -s . foo && error "'ln -s .' worked after removing cwd"
5783         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5784 }
5785 run_test 48b "Access removed working dir (should return errors)="
5786
5787 test_48c() { # bug 2350
5788         #lctl set_param debug=-1
5789         #set -vx
5790         rm -rf $DIR/$tdir
5791         test_mkdir -p $DIR/$tdir/dir
5792         cd $DIR/$tdir/dir
5793         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5794         $TRACE touch foo && error "touch foo worked after removing cwd"
5795         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5796         touch .foo && error "touch .foo worked after removing cwd"
5797         mkdir .foo && error "mkdir .foo worked after removing cwd"
5798         $TRACE ls . && error "'ls .' worked after removing cwd"
5799         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5800         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5801         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5802         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5803         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5804 }
5805 run_test 48c "Access removed working subdir (should return errors)"
5806
5807 test_48d() { # bug 2350
5808         #lctl set_param debug=-1
5809         #set -vx
5810         rm -rf $DIR/$tdir
5811         test_mkdir -p $DIR/$tdir/dir
5812         cd $DIR/$tdir/dir
5813         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5814         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5815         $TRACE touch foo && error "'touch foo' worked after removing parent"
5816         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5817         touch .foo && error "'touch .foo' worked after removing parent"
5818         mkdir .foo && error "mkdir .foo worked after removing parent"
5819         $TRACE ls . && error "'ls .' worked after removing parent"
5820         $TRACE ls .. && error "'ls ..' worked after removing parent"
5821         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5822         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5823         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5824         true
5825 }
5826 run_test 48d "Access removed parent subdir (should return errors)"
5827
5828 test_48e() { # bug 4134
5829         #lctl set_param debug=-1
5830         #set -vx
5831         rm -rf $DIR/$tdir
5832         test_mkdir -p $DIR/$tdir/dir
5833         cd $DIR/$tdir/dir
5834         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5835         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5836         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5837         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5838         # On a buggy kernel addition of "touch foo" after cd .. will
5839         # produce kernel oops in lookup_hash_it
5840         touch ../foo && error "'cd ..' worked after recreate parent"
5841         cd $DIR
5842         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5843 }
5844 run_test 48e "Access to recreated parent subdir (should return errors)"
5845
5846 test_48f() {
5847         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5848                 skip "need MDS >= 2.13.55"
5849         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5850         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5851                 skip "needs different host for mdt1 mdt2"
5852         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5853
5854         $LFS mkdir -i0 $DIR/$tdir
5855         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5856
5857         for d in sub1 sub2 sub3; do
5858                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5859                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5860                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5861         done
5862
5863         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5864 }
5865 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5866
5867 test_49() { # LU-1030
5868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5869         remote_ost_nodsh && skip "remote OST with nodsh"
5870
5871         # get ost1 size - $FSNAME-OST0000
5872         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5873                 awk '{ print $4 }')
5874         # write 800M at maximum
5875         [[ $ost1_size -lt 2 ]] && ost1_size=2
5876         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5877
5878         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5879         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5880         local dd_pid=$!
5881
5882         # change max_pages_per_rpc while writing the file
5883         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5884         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5885         # loop until dd process exits
5886         while ps ax -opid | grep -wq $dd_pid; do
5887                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5888                 sleep $((RANDOM % 5 + 1))
5889         done
5890         # restore original max_pages_per_rpc
5891         $LCTL set_param $osc1_mppc=$orig_mppc
5892         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5893 }
5894 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5895
5896 test_50() {
5897         # bug 1485
5898         test_mkdir $DIR/$tdir
5899         cd $DIR/$tdir
5900         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5901 }
5902 run_test 50 "special situations: /proc symlinks  ==============="
5903
5904 test_51a() {    # was test_51
5905         # bug 1516 - create an empty entry right after ".." then split dir
5906         test_mkdir -c1 $DIR/$tdir
5907         touch $DIR/$tdir/foo
5908         $MCREATE $DIR/$tdir/bar
5909         rm $DIR/$tdir/foo
5910         createmany -m $DIR/$tdir/longfile 201
5911         FNUM=202
5912         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5913                 $MCREATE $DIR/$tdir/longfile$FNUM
5914                 FNUM=$(($FNUM + 1))
5915                 echo -n "+"
5916         done
5917         echo
5918         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5919 }
5920 run_test 51a "special situations: split htree with empty entry =="
5921
5922 cleanup_print_lfs_df () {
5923         trap 0
5924         $LFS df
5925         $LFS df -i
5926 }
5927
5928 test_51b() {
5929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5930
5931         local dir=$DIR/$tdir
5932         local nrdirs=$((65536 + 100))
5933
5934         # cleanup the directory
5935         rm -fr $dir
5936
5937         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5938
5939         $LFS df
5940         $LFS df -i
5941         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5942         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5943         [[ $numfree -lt $nrdirs ]] &&
5944                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5945
5946         # need to check free space for the directories as well
5947         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5948         numfree=$(( blkfree / $(fs_inode_ksize) ))
5949         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5950
5951         trap cleanup_print_lfs_df EXIT
5952
5953         # create files
5954         createmany -d $dir/d $nrdirs || {
5955                 unlinkmany $dir/d $nrdirs
5956                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5957         }
5958
5959         # really created :
5960         nrdirs=$(ls -U $dir | wc -l)
5961
5962         # unlink all but 100 subdirectories, then check it still works
5963         local left=100
5964         local delete=$((nrdirs - left))
5965
5966         $LFS df
5967         $LFS df -i
5968
5969         # for ldiskfs the nlink count should be 1, but this is OSD specific
5970         # and so this is listed for informational purposes only
5971         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5972         unlinkmany -d $dir/d $delete ||
5973                 error "unlink of first $delete subdirs failed"
5974
5975         echo "nlink between: $(stat -c %h $dir)"
5976         local found=$(ls -U $dir | wc -l)
5977         [ $found -ne $left ] &&
5978                 error "can't find subdirs: found only $found, expected $left"
5979
5980         unlinkmany -d $dir/d $delete $left ||
5981                 error "unlink of second $left subdirs failed"
5982         # regardless of whether the backing filesystem tracks nlink accurately
5983         # or not, the nlink count shouldn't be more than "." and ".." here
5984         local after=$(stat -c %h $dir)
5985         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5986                 echo "nlink after: $after"
5987
5988         cleanup_print_lfs_df
5989 }
5990 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5991
5992 test_51d_sub() {
5993         local stripecount=$1
5994         local nfiles=$2
5995
5996         log "create files with stripecount=$stripecount"
5997         $LFS setstripe -C $stripecount $DIR/$tdir
5998         createmany -o $DIR/$tdir/t- $nfiles
5999         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6000         for ((n = 0; n < $OSTCOUNT; n++)); do
6001                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6002                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6003                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6004                             '($1 == '$n') { objs += 1 } \
6005                             END { printf("%0.0f", objs) }')
6006                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6007         done
6008         unlinkmany $DIR/$tdir/t- $nfiles
6009         rm  -f $TMP/$tfile
6010
6011         local nlast
6012         local min=4
6013         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6014
6015         # For some combinations of stripecount and OSTCOUNT current code
6016         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6017         # than others. Rather than skipping this test entirely, check that
6018         # and keep testing to ensure imbalance does not get worse. LU-15282
6019         (( (OSTCOUNT == 6 && stripecount == 4) ||
6020            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6021            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6022         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6023                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6024                         { $LFS df && $LFS df -i &&
6025                         error "stripecount=$stripecount: " \
6026                               "OST $n has fewer objects vs. OST $nlast " \
6027                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6028                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6029                         { $LFS df && $LFS df -i &&
6030                         error "stripecount=$stripecount: " \
6031                               "OST $n has more objects vs. OST $nlast " \
6032                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6033
6034                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6035                         { $LFS df && $LFS df -i &&
6036                         error "stripecount=$stripecount: " \
6037                               "OST $n has fewer #0 objects vs. OST $nlast " \
6038                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6039                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6040                         { $LFS df && $LFS df -i &&
6041                         error "stripecount=$stripecount: " \
6042                               "OST $n has more #0 objects vs. OST $nlast " \
6043                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6044         done
6045 }
6046
6047 test_51d() {
6048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6049         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6050
6051         local stripecount
6052         local per_ost=100
6053         local nfiles=$((per_ost * OSTCOUNT))
6054         local mdts=$(comma_list $(mdts_nodes))
6055         local param="osp.*.create_count"
6056         local qos_old=$(do_facet mds1 \
6057                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6058
6059         do_nodes $mdts \
6060                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6061         stack_trap "do_nodes $mdts \
6062                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6063
6064         test_mkdir $DIR/$tdir
6065         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6066         (( dirstripes > 0 )) || dirstripes=1
6067
6068         # Ensure enough OST objects precreated for tests to pass without
6069         # running out of objects.  This is an LOV r-r OST algorithm test,
6070         # not an OST object precreation test.
6071         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6072         (( old >= nfiles )) ||
6073         {
6074                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6075
6076                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6077                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6078
6079                 # trigger precreation from all MDTs for all OSTs
6080                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6081                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6082                 done
6083         }
6084
6085         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6086                 sleep 8  # allow object precreation to catch up
6087                 test_51d_sub $stripecount $nfiles
6088         done
6089 }
6090 run_test 51d "check LOV round-robin OST object distribution"
6091
6092 test_51e() {
6093         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6094                 skip_env "ldiskfs only test"
6095         fi
6096
6097         test_mkdir -c1 $DIR/$tdir
6098         test_mkdir -c1 $DIR/$tdir/d0
6099
6100         touch $DIR/$tdir/d0/foo
6101         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6102                 error "file exceed 65000 nlink limit!"
6103         unlinkmany $DIR/$tdir/d0/f- 65001
6104         return 0
6105 }
6106 run_test 51e "check file nlink limit"
6107
6108 test_51f() {
6109         test_mkdir $DIR/$tdir
6110
6111         local max=100000
6112         local ulimit_old=$(ulimit -n)
6113         local spare=20 # number of spare fd's for scripts/libraries, etc.
6114         local mdt=$($LFS getstripe -m $DIR/$tdir)
6115         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6116
6117         echo "MDT$mdt numfree=$numfree, max=$max"
6118         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6119         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6120                 while ! ulimit -n $((numfree + spare)); do
6121                         numfree=$((numfree * 3 / 4))
6122                 done
6123                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6124         else
6125                 echo "left ulimit at $ulimit_old"
6126         fi
6127
6128         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6129                 unlinkmany $DIR/$tdir/f $numfree
6130                 error "create+open $numfree files in $DIR/$tdir failed"
6131         }
6132         ulimit -n $ulimit_old
6133
6134         # if createmany exits at 120s there will be fewer than $numfree files
6135         unlinkmany $DIR/$tdir/f $numfree || true
6136 }
6137 run_test 51f "check many open files limit"
6138
6139 test_52a() {
6140         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6141         test_mkdir $DIR/$tdir
6142         touch $DIR/$tdir/foo
6143         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6144         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6145         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6146         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6147         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6148                                         error "link worked"
6149         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6150         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6151         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6152                                                      error "lsattr"
6153         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6154         cp -r $DIR/$tdir $TMP/
6155         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6156 }
6157 run_test 52a "append-only flag test (should return errors)"
6158
6159 test_52b() {
6160         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6161         test_mkdir $DIR/$tdir
6162         touch $DIR/$tdir/foo
6163         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6164         cat test > $DIR/$tdir/foo && error "cat test worked"
6165         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6166         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6167         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6168                                         error "link worked"
6169         echo foo >> $DIR/$tdir/foo && error "echo worked"
6170         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6171         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6172         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6173         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6174                                                         error "lsattr"
6175         chattr -i $DIR/$tdir/foo || error "chattr failed"
6176
6177         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6178 }
6179 run_test 52b "immutable flag test (should return errors) ======="
6180
6181 test_53() {
6182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6183         remote_mds_nodsh && skip "remote MDS with nodsh"
6184         remote_ost_nodsh && skip "remote OST with nodsh"
6185
6186         local param
6187         local param_seq
6188         local ostname
6189         local mds_last
6190         local mds_last_seq
6191         local ost_last
6192         local ost_last_seq
6193         local ost_last_id
6194         local ostnum
6195         local node
6196         local found=false
6197         local support_last_seq=true
6198
6199         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6200                 support_last_seq=false
6201
6202         # only test MDT0000
6203         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6204         local value
6205         for value in $(do_facet $SINGLEMDS \
6206                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6207                 param=$(echo ${value[0]} | cut -d "=" -f1)
6208                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6209
6210                 if $support_last_seq; then
6211                         param_seq=$(echo $param |
6212                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6213                         mds_last_seq=$(do_facet $SINGLEMDS \
6214                                        $LCTL get_param -n $param_seq)
6215                 fi
6216                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6217
6218                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6219                 node=$(facet_active_host ost$((ostnum+1)))
6220                 param="obdfilter.$ostname.last_id"
6221                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6222                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6223                         ost_last_id=$ost_last
6224
6225                         if $support_last_seq; then
6226                                 ost_last_id=$(echo $ost_last |
6227                                               awk -F':' '{print $2}' |
6228                                               sed -e "s/^0x//g")
6229                                 ost_last_seq=$(echo $ost_last |
6230                                                awk -F':' '{print $1}')
6231                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6232                         fi
6233
6234                         if [[ $ost_last_id != $mds_last ]]; then
6235                                 error "$ost_last_id != $mds_last"
6236                         else
6237                                 found=true
6238                                 break
6239                         fi
6240                 done
6241         done
6242         $found || error "can not match last_seq/last_id for $mdtosc"
6243         return 0
6244 }
6245 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6246
6247 test_54a() {
6248         perl -MSocket -e ';' || skip "no Socket perl module installed"
6249
6250         $SOCKETSERVER $DIR/socket ||
6251                 error "$SOCKETSERVER $DIR/socket failed: $?"
6252         $SOCKETCLIENT $DIR/socket ||
6253                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6254         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6255 }
6256 run_test 54a "unix domain socket test =========================="
6257
6258 test_54b() {
6259         f="$DIR/f54b"
6260         mknod $f c 1 3
6261         chmod 0666 $f
6262         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6263 }
6264 run_test 54b "char device works in lustre ======================"
6265
6266 find_loop_dev() {
6267         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6268         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6269         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6270
6271         for i in $(seq 3 7); do
6272                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6273                 LOOPDEV=$LOOPBASE$i
6274                 LOOPNUM=$i
6275                 break
6276         done
6277 }
6278
6279 cleanup_54c() {
6280         local rc=0
6281         loopdev="$DIR/loop54c"
6282
6283         trap 0
6284         $UMOUNT $DIR/$tdir || rc=$?
6285         losetup -d $loopdev || true
6286         losetup -d $LOOPDEV || true
6287         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6288         return $rc
6289 }
6290
6291 test_54c() {
6292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6293
6294         loopdev="$DIR/loop54c"
6295
6296         find_loop_dev
6297         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6298         trap cleanup_54c EXIT
6299         mknod $loopdev b 7 $LOOPNUM
6300         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6301         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6302         losetup $loopdev $DIR/$tfile ||
6303                 error "can't set up $loopdev for $DIR/$tfile"
6304         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6305         test_mkdir $DIR/$tdir
6306         mount -t ext2 $loopdev $DIR/$tdir ||
6307                 error "error mounting $loopdev on $DIR/$tdir"
6308         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6309                 error "dd write"
6310         df $DIR/$tdir
6311         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6312                 error "dd read"
6313         cleanup_54c
6314 }
6315 run_test 54c "block device works in lustre ====================="
6316
6317 test_54d() {
6318         local pipe="$DIR/$tfile.pipe"
6319         local string="aaaaaa"
6320
6321         mknod $pipe p
6322         echo -n "$string" > $pipe &
6323         local result=$(cat $pipe)
6324         [[ "$result" == "$string" ]] || error "$result != $string"
6325 }
6326 run_test 54d "fifo device works in lustre ======================"
6327
6328 test_54e() {
6329         f="$DIR/f54e"
6330         string="aaaaaa"
6331         cp -aL /dev/console $f
6332         echo $string > $f || error "echo $string to $f failed"
6333 }
6334 run_test 54e "console/tty device works in lustre ======================"
6335
6336 test_56a() {
6337         local numfiles=3
6338         local numdirs=2
6339         local dir=$DIR/$tdir
6340
6341         rm -rf $dir
6342         test_mkdir -p $dir/dir
6343         for i in $(seq $numfiles); do
6344                 touch $dir/file$i
6345                 touch $dir/dir/file$i
6346         done
6347
6348         local numcomp=$($LFS getstripe --component-count $dir)
6349
6350         [[ $numcomp == 0 ]] && numcomp=1
6351
6352         # test lfs getstripe with --recursive
6353         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6354
6355         [[ $filenum -eq $((numfiles * 2)) ]] ||
6356                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6357         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6358         [[ $filenum -eq $numfiles ]] ||
6359                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6360         echo "$LFS getstripe showed obdidx or l_ost_idx"
6361
6362         # test lfs getstripe with file instead of dir
6363         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6364         [[ $filenum -eq 1 ]] ||
6365                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6366         echo "$LFS getstripe file1 passed"
6367
6368         #test lfs getstripe with --verbose
6369         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6370         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6371                 error "$LFS getstripe --verbose $dir: "\
6372                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6373         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6374                 error "$LFS getstripe $dir: showed lmm_magic"
6375
6376         #test lfs getstripe with -v prints lmm_fid
6377         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6378         local countfids=$((numdirs + numfiles * numcomp))
6379         [[ $filenum -eq $countfids ]] ||
6380                 error "$LFS getstripe -v $dir: "\
6381                       "got $filenum want $countfids lmm_fid"
6382         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6383                 error "$LFS getstripe $dir: showed lmm_fid by default"
6384         echo "$LFS getstripe --verbose passed"
6385
6386         #check for FID information
6387         local fid1=$($LFS getstripe --fid $dir/file1)
6388         local fid2=$($LFS getstripe --verbose $dir/file1 |
6389                      awk '/lmm_fid: / { print $2; exit; }')
6390         local fid3=$($LFS path2fid $dir/file1)
6391
6392         [ "$fid1" != "$fid2" ] &&
6393                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6394         [ "$fid1" != "$fid3" ] &&
6395                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6396         echo "$LFS getstripe --fid passed"
6397
6398         #test lfs getstripe with --obd
6399         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6400                 error "$LFS getstripe --obd wrong_uuid: should return error"
6401
6402         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6403
6404         local ostidx=1
6405         local obduuid=$(ostuuid_from_index $ostidx)
6406         local found=$($LFS getstripe -r --obd $obduuid $dir |
6407                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6408
6409         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6410         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6411                 ((filenum--))
6412         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6413                 ((filenum--))
6414
6415         [[ $found -eq $filenum ]] ||
6416                 error "$LFS getstripe --obd: found $found expect $filenum"
6417         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6418                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6419                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6420                 error "$LFS getstripe --obd: should not show file on other obd"
6421         echo "$LFS getstripe --obd passed"
6422 }
6423 run_test 56a "check $LFS getstripe"
6424
6425 test_56b() {
6426         local dir=$DIR/$tdir
6427         local numdirs=3
6428
6429         test_mkdir $dir
6430         for i in $(seq $numdirs); do
6431                 test_mkdir $dir/dir$i
6432         done
6433
6434         # test lfs getdirstripe default mode is non-recursion, which is
6435         # different from lfs getstripe
6436         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6437
6438         [[ $dircnt -eq 1 ]] ||
6439                 error "$LFS getdirstripe: found $dircnt, not 1"
6440         dircnt=$($LFS getdirstripe --recursive $dir |
6441                 grep -c lmv_stripe_count)
6442         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6443                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6444 }
6445 run_test 56b "check $LFS getdirstripe"
6446
6447 test_56bb() {
6448         verify_yaml_available || skip_env "YAML verification not installed"
6449         local output_file=$DIR/$tfile.out
6450
6451         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6452
6453         cat $output_file
6454         cat $output_file | verify_yaml || error "layout is not valid YAML"
6455 }
6456 run_test 56bb "check $LFS getdirstripe layout is YAML"
6457
6458 test_56c() {
6459         remote_ost_nodsh && skip "remote OST with nodsh"
6460
6461         local ost_idx=0
6462         local ost_name=$(ostname_from_index $ost_idx)
6463         local old_status=$(ost_dev_status $ost_idx)
6464         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6465
6466         [[ -z "$old_status" ]] ||
6467                 skip_env "OST $ost_name is in $old_status status"
6468
6469         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6470         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6471                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6472         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6473                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6474                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6475         fi
6476
6477         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6478                 error "$LFS df -v showing inactive devices"
6479         sleep_maxage
6480
6481         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6482
6483         [[ "$new_status" =~ "D" ]] ||
6484                 error "$ost_name status is '$new_status', missing 'D'"
6485         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6486                 [[ "$new_status" =~ "N" ]] ||
6487                         error "$ost_name status is '$new_status', missing 'N'"
6488         fi
6489         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6490                 [[ "$new_status" =~ "f" ]] ||
6491                         error "$ost_name status is '$new_status', missing 'f'"
6492         fi
6493
6494         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6495         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6496                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6497         [[ -z "$p" ]] && restore_lustre_params < $p || true
6498         sleep_maxage
6499
6500         new_status=$(ost_dev_status $ost_idx)
6501         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6502                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6503         # can't check 'f' as devices may actually be on flash
6504 }
6505 run_test 56c "check 'lfs df' showing device status"
6506
6507 test_56d() {
6508         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6509         local osts=$($LFS df -v $MOUNT | grep -c OST)
6510
6511         $LFS df $MOUNT
6512
6513         (( mdts == MDSCOUNT )) ||
6514                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6515         (( osts == OSTCOUNT )) ||
6516                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6517 }
6518 run_test 56d "'lfs df -v' prints only configured devices"
6519
6520 test_56e() {
6521         err_enoent=2 # No such file or directory
6522         err_eopnotsupp=95 # Operation not supported
6523
6524         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6525         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6526
6527         # Check for handling of path not exists
6528         output=$($LFS df $enoent_mnt 2>&1)
6529         ret=$?
6530
6531         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6532         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6533                 error "expect failure $err_enoent, not $ret"
6534
6535         # Check for handling of non-Lustre FS
6536         output=$($LFS df $notsup_mnt)
6537         ret=$?
6538
6539         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6540         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6541                 error "expect success $err_eopnotsupp, not $ret"
6542
6543         # Check for multiple LustreFS argument
6544         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6545         ret=$?
6546
6547         [[ $output -eq 3 && $ret -eq 0 ]] ||
6548                 error "expect success 3, not $output, rc = $ret"
6549
6550         # Check for correct non-Lustre FS handling among multiple
6551         # LustreFS argument
6552         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6553                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6554         ret=$?
6555
6556         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6557                 error "expect success 2, not $output, rc = $ret"
6558 }
6559 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6560
6561 NUMFILES=3
6562 NUMDIRS=3
6563 setup_56() {
6564         local local_tdir="$1"
6565         local local_numfiles="$2"
6566         local local_numdirs="$3"
6567         local dir_params="$4"
6568         local dir_stripe_params="$5"
6569
6570         if [ ! -d "$local_tdir" ] ; then
6571                 test_mkdir -p $dir_stripe_params $local_tdir
6572                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6573                 for i in $(seq $local_numfiles) ; do
6574                         touch $local_tdir/file$i
6575                 done
6576                 for i in $(seq $local_numdirs) ; do
6577                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6578                         for j in $(seq $local_numfiles) ; do
6579                                 touch $local_tdir/dir$i/file$j
6580                         done
6581                 done
6582         fi
6583 }
6584
6585 setup_56_special() {
6586         local local_tdir=$1
6587         local local_numfiles=$2
6588         local local_numdirs=$3
6589
6590         setup_56 $local_tdir $local_numfiles $local_numdirs
6591
6592         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6593                 for i in $(seq $local_numfiles) ; do
6594                         mknod $local_tdir/loop${i}b b 7 $i
6595                         mknod $local_tdir/null${i}c c 1 3
6596                         ln -s $local_tdir/file1 $local_tdir/link${i}
6597                 done
6598                 for i in $(seq $local_numdirs) ; do
6599                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6600                         mknod $local_tdir/dir$i/null${i}c c 1 3
6601                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6602                 done
6603         fi
6604 }
6605
6606 test_56g() {
6607         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6608         local expected=$(($NUMDIRS + 2))
6609
6610         setup_56 $dir $NUMFILES $NUMDIRS
6611
6612         # test lfs find with -name
6613         for i in $(seq $NUMFILES) ; do
6614                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6615
6616                 [ $nums -eq $expected ] ||
6617                         error "lfs find -name '*$i' $dir wrong: "\
6618                               "found $nums, expected $expected"
6619         done
6620 }
6621 run_test 56g "check lfs find -name"
6622
6623 test_56h() {
6624         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6625         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628
6629         # test lfs find with ! -name
6630         for i in $(seq $NUMFILES) ; do
6631                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6632
6633                 [ $nums -eq $expected ] ||
6634                         error "lfs find ! -name '*$i' $dir wrong: "\
6635                               "found $nums, expected $expected"
6636         done
6637 }
6638 run_test 56h "check lfs find ! -name"
6639
6640 test_56i() {
6641         local dir=$DIR/$tdir
6642
6643         test_mkdir $dir
6644
6645         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6646         local out=$($cmd)
6647
6648         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6649 }
6650 run_test 56i "check 'lfs find -ost UUID' skips directories"
6651
6652 test_56j() {
6653         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6654
6655         setup_56_special $dir $NUMFILES $NUMDIRS
6656
6657         local expected=$((NUMDIRS + 1))
6658         local cmd="$LFS find -type d $dir"
6659         local nums=$($cmd | wc -l)
6660
6661         [ $nums -eq $expected ] ||
6662                 error "'$cmd' wrong: found $nums, expected $expected"
6663 }
6664 run_test 56j "check lfs find -type d"
6665
6666 test_56k() {
6667         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6668
6669         setup_56_special $dir $NUMFILES $NUMDIRS
6670
6671         local expected=$(((NUMDIRS + 1) * NUMFILES))
6672         local cmd="$LFS find -type f $dir"
6673         local nums=$($cmd | wc -l)
6674
6675         [ $nums -eq $expected ] ||
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677 }
6678 run_test 56k "check lfs find -type f"
6679
6680 test_56l() {
6681         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6682
6683         setup_56_special $dir $NUMFILES $NUMDIRS
6684
6685         local expected=$((NUMDIRS + NUMFILES))
6686         local cmd="$LFS find -type b $dir"
6687         local nums=$($cmd | wc -l)
6688
6689         [ $nums -eq $expected ] ||
6690                 error "'$cmd' wrong: found $nums, expected $expected"
6691 }
6692 run_test 56l "check lfs find -type b"
6693
6694 test_56m() {
6695         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6696
6697         setup_56_special $dir $NUMFILES $NUMDIRS
6698
6699         local expected=$((NUMDIRS + NUMFILES))
6700         local cmd="$LFS find -type c $dir"
6701         local nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704 }
6705 run_test 56m "check lfs find -type c"
6706
6707 test_56n() {
6708         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6709         setup_56_special $dir $NUMFILES $NUMDIRS
6710
6711         local expected=$((NUMDIRS + NUMFILES))
6712         local cmd="$LFS find -type l $dir"
6713         local nums=$($cmd | wc -l)
6714
6715         [ $nums -eq $expected ] ||
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717 }
6718 run_test 56n "check lfs find -type l"
6719
6720 test_56o() {
6721         local dir=$DIR/$tdir
6722
6723         setup_56 $dir $NUMFILES $NUMDIRS
6724         utime $dir/file1 > /dev/null || error "utime (1)"
6725         utime $dir/file2 > /dev/null || error "utime (2)"
6726         utime $dir/dir1 > /dev/null || error "utime (3)"
6727         utime $dir/dir2 > /dev/null || error "utime (4)"
6728         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6729         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6730
6731         local expected=4
6732         local nums=$($LFS find -mtime +0 $dir | wc -l)
6733
6734         [ $nums -eq $expected ] ||
6735                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6736
6737         expected=12
6738         cmd="$LFS find -mtime 0 $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742 }
6743 run_test 56o "check lfs find -mtime for old files"
6744
6745 test_56ob() {
6746         local dir=$DIR/$tdir
6747         local expected=1
6748         local count=0
6749
6750         # just to make sure there is something that won't be found
6751         test_mkdir $dir
6752         touch $dir/$tfile.now
6753
6754         for age in year week day hour min; do
6755                 count=$((count + 1))
6756
6757                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6758                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6759                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6760
6761                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6762                 local nums=$($cmd | wc -l)
6763                 [ $nums -eq $expected ] ||
6764                         error "'$cmd' wrong: found $nums, expected $expected"
6765
6766                 cmd="$LFS find $dir -atime $count${age:0:1}"
6767                 nums=$($cmd | wc -l)
6768                 [ $nums -eq $expected ] ||
6769                         error "'$cmd' wrong: found $nums, expected $expected"
6770         done
6771
6772         sleep 2
6773         cmd="$LFS find $dir -ctime +1s -type f"
6774         nums=$($cmd | wc -l)
6775         (( $nums == $count * 2 + 1)) ||
6776                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6777 }
6778 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6779
6780 test_newerXY_base() {
6781         local x=$1
6782         local y=$2
6783         local dir=$DIR/$tdir
6784         local ref
6785         local negref
6786
6787         if [ $y == "t" ]; then
6788                 if [ $x == "b" ]; then
6789                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6790                 else
6791                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6792                 fi
6793         else
6794                 ref=$DIR/$tfile.newer.$x$y
6795                 touch $ref || error "touch $ref failed"
6796         fi
6797
6798         echo "before = $ref"
6799         sleep 2
6800         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6801         sleep 2
6802         if [ $y == "t" ]; then
6803                 if [ $x == "b" ]; then
6804                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6805                 else
6806                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6807                 fi
6808         else
6809                 negref=$DIR/$tfile.negnewer.$x$y
6810                 touch $negref || error "touch $negref failed"
6811         fi
6812
6813         echo "after = $negref"
6814         local cmd="$LFS find $dir -newer$x$y $ref"
6815         local nums=$(eval $cmd | wc -l)
6816         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6817
6818         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6819                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6820
6821         cmd="$LFS find $dir ! -newer$x$y $negref"
6822         nums=$(eval $cmd | wc -l)
6823         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6824                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6825
6826         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6827         nums=$(eval $cmd | wc -l)
6828         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6829                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6830
6831         rm -rf $DIR/*
6832 }
6833
6834 test_56oc() {
6835         test_newerXY_base "a" "a"
6836         test_newerXY_base "a" "m"
6837         test_newerXY_base "a" "c"
6838         test_newerXY_base "m" "a"
6839         test_newerXY_base "m" "m"
6840         test_newerXY_base "m" "c"
6841         test_newerXY_base "c" "a"
6842         test_newerXY_base "c" "m"
6843         test_newerXY_base "c" "c"
6844
6845         test_newerXY_base "a" "t"
6846         test_newerXY_base "m" "t"
6847         test_newerXY_base "c" "t"
6848
6849         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6850            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6851                 ! btime_supported && echo "btime unsupported" && return 0
6852
6853         test_newerXY_base "b" "b"
6854         test_newerXY_base "b" "t"
6855 }
6856 run_test 56oc "check lfs find -newerXY work"
6857
6858 btime_supported() {
6859         local dir=$DIR/$tdir
6860         local rc
6861
6862         mkdir -p $dir
6863         touch $dir/$tfile
6864         $LFS find $dir -btime -1d -type f
6865         rc=$?
6866         rm -rf $dir
6867         return $rc
6868 }
6869
6870 test_56od() {
6871         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6872                 ! btime_supported && skip "btime unsupported on MDS"
6873
6874         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6875                 ! btime_supported && skip "btime unsupported on clients"
6876
6877         local dir=$DIR/$tdir
6878         local ref=$DIR/$tfile.ref
6879         local negref=$DIR/$tfile.negref
6880
6881         mkdir $dir || error "mkdir $dir failed"
6882         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6883         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6884         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6885         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6886         touch $ref || error "touch $ref failed"
6887         # sleep 3 seconds at least
6888         sleep 3
6889
6890         local before=$(do_facet mds1 date +%s)
6891         local skew=$(($(date +%s) - before + 1))
6892
6893         if (( skew < 0 && skew > -5 )); then
6894                 sleep $((0 - skew + 1))
6895                 skew=0
6896         fi
6897
6898         # Set the dir stripe params to limit files all on MDT0,
6899         # otherwise we need to calc the max clock skew between
6900         # the client and MDTs.
6901         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6902         sleep 2
6903         touch $negref || error "touch $negref failed"
6904
6905         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6906         local nums=$($cmd | wc -l)
6907         local expected=$(((NUMFILES + 1) * NUMDIRS))
6908
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911
6912         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6913         nums=$($cmd | wc -l)
6914         expected=$((NUMFILES + 1))
6915         [ $nums -eq $expected ] ||
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917
6918         [ $skew -lt 0 ] && return
6919
6920         local after=$(do_facet mds1 date +%s)
6921         local age=$((after - before + 1 + skew))
6922
6923         cmd="$LFS find $dir -btime -${age}s -type f"
6924         nums=$($cmd | wc -l)
6925         expected=$(((NUMFILES + 1) * NUMDIRS))
6926
6927         echo "Clock skew between client and server: $skew, age:$age"
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930
6931         expected=$(($NUMDIRS + 1))
6932         cmd="$LFS find $dir -btime -${age}s -type d"
6933         nums=$($cmd | wc -l)
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936         rm -f $ref $negref || error "Failed to remove $ref $negref"
6937 }
6938 run_test 56od "check lfs find -btime with units"
6939
6940 test_56p() {
6941         [ $RUNAS_ID -eq $UID ] &&
6942                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6943
6944         local dir=$DIR/$tdir
6945
6946         setup_56 $dir $NUMFILES $NUMDIRS
6947         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6948
6949         local expected=$NUMFILES
6950         local cmd="$LFS find -uid $RUNAS_ID $dir"
6951         local nums=$($cmd | wc -l)
6952
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6957         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6958         nums=$($cmd | wc -l)
6959         [ $nums -eq $expected ] ||
6960                 error "'$cmd' wrong: found $nums, expected $expected"
6961 }
6962 run_test 56p "check lfs find -uid and ! -uid"
6963
6964 test_56q() {
6965         [ $RUNAS_ID -eq $UID ] &&
6966                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6967
6968         local dir=$DIR/$tdir
6969
6970         setup_56 $dir $NUMFILES $NUMDIRS
6971         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6972
6973         local expected=$NUMFILES
6974         local cmd="$LFS find -gid $RUNAS_GID $dir"
6975         local nums=$($cmd | wc -l)
6976
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6981         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985 }
6986 run_test 56q "check lfs find -gid and ! -gid"
6987
6988 test_56r() {
6989         local dir=$DIR/$tdir
6990
6991         setup_56 $dir $NUMFILES $NUMDIRS
6992
6993         local expected=12
6994         local cmd="$LFS find -size 0 -type f -lazy $dir"
6995         local nums=$($cmd | wc -l)
6996
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999         cmd="$LFS find -size 0 -type f $dir"
7000         nums=$($cmd | wc -l)
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=0
7005         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009         cmd="$LFS find ! -size 0 -type f $dir"
7010         nums=$($cmd | wc -l)
7011         [ $nums -eq $expected ] ||
7012                 error "'$cmd' wrong: found $nums, expected $expected"
7013
7014         echo "test" > $dir/$tfile
7015         echo "test2" > $dir/$tfile.2 && sync
7016         expected=1
7017         cmd="$LFS find -size 5 -type f -lazy $dir"
7018         nums=$($cmd | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021         cmd="$LFS find -size 5 -type f $dir"
7022         nums=$($cmd | wc -l)
7023         [ $nums -eq $expected ] ||
7024                 error "'$cmd' wrong: found $nums, expected $expected"
7025
7026         expected=1
7027         cmd="$LFS find -size +5 -type f -lazy $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031         cmd="$LFS find -size +5 -type f $dir"
7032         nums=$($cmd | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         expected=2
7037         cmd="$LFS find -size +0 -type f -lazy $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041         cmd="$LFS find -size +0 -type f $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045
7046         expected=2
7047         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7048         nums=$($cmd | wc -l)
7049         [ $nums -eq $expected ] ||
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051         cmd="$LFS find ! -size -5 -type f $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055
7056         expected=12
7057         cmd="$LFS find -size -5 -type f -lazy $dir"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061         cmd="$LFS find -size -5 -type f $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065 }
7066 run_test 56r "check lfs find -size works"
7067
7068 test_56ra_sub() {
7069         local expected=$1
7070         local glimpses=$2
7071         local cmd="$3"
7072
7073         cancel_lru_locks $OSC
7074
7075         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7076         local nums=$($cmd | wc -l)
7077
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080
7081         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7082
7083         if (( rpcs_before + glimpses != rpcs_after )); then
7084                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7085                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7086
7087                 if [[ $glimpses == 0 ]]; then
7088                         error "'$cmd' should not send glimpse RPCs to OST"
7089                 else
7090                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7091                 fi
7092         fi
7093 }
7094
7095 test_56ra() {
7096         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7097                 skip "MDS < 2.12.58 doesn't return LSOM data"
7098         local dir=$DIR/$tdir
7099         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7100
7101         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7102
7103         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7104         $LCTL set_param -n llite.*.statahead_agl=0
7105         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7106
7107         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7108         # open and close all files to ensure LSOM is updated
7109         cancel_lru_locks $OSC
7110         find $dir -type f | xargs cat > /dev/null
7111
7112         #   expect_found  glimpse_rpcs  command_to_run
7113         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7114         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7115         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7116         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7117
7118         echo "test" > $dir/$tfile
7119         echo "test2" > $dir/$tfile.2 && sync
7120         cancel_lru_locks $OSC
7121         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7122
7123         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7124         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7125         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7126         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7127
7128         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7129         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7130         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7131         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7132         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7133         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7134 }
7135 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7136
7137 test_56rb() {
7138         local dir=$DIR/$tdir
7139         local tmp=$TMP/$tfile.log
7140         local mdt_idx;
7141
7142         test_mkdir -p $dir || error "failed to mkdir $dir"
7143         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7144                 error "failed to setstripe $dir/$tfile"
7145         mdt_idx=$($LFS getdirstripe -i $dir)
7146         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7147
7148         stack_trap "rm -f $tmp" EXIT
7149         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7150         ! grep -q obd_uuid $tmp ||
7151                 error "failed to find --size +100K --ost 0 $dir"
7152         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7153         ! grep -q obd_uuid $tmp ||
7154                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7155 }
7156 run_test 56rb "check lfs find --size --ost/--mdt works"
7157
7158 test_56rc() {
7159         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7160         local dir=$DIR/$tdir
7161         local found
7162
7163         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7164         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7165         (( $MDSCOUNT > 2 )) &&
7166                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7167         mkdir $dir/$tdir-{1..10}
7168         touch $dir/$tfile-{1..10}
7169
7170         found=$($LFS find $dir --mdt-count 2 | wc -l)
7171         expect=11
7172         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7173
7174         found=$($LFS find $dir -T +1 | wc -l)
7175         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7176         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7177
7178         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7179         expect=11
7180         (( $found == $expect )) || error "found $found all_char, expect $expect"
7181
7182         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7183         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7184         (( $found == $expect )) || error "found $found all_char, expect $expect"
7185 }
7186 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7187
7188 test_56s() { # LU-611 #LU-9369
7189         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7190
7191         local dir=$DIR/$tdir
7192         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7193
7194         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7195         for i in $(seq $NUMDIRS); do
7196                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7197         done
7198
7199         local expected=$NUMDIRS
7200         local cmd="$LFS find -c $OSTCOUNT $dir"
7201         local nums=$($cmd | wc -l)
7202
7203         [ $nums -eq $expected ] || {
7204                 $LFS getstripe -R $dir
7205                 error "'$cmd' wrong: found $nums, expected $expected"
7206         }
7207
7208         expected=$((NUMDIRS + onestripe))
7209         cmd="$LFS find -stripe-count +0 -type f $dir"
7210         nums=$($cmd | wc -l)
7211         [ $nums -eq $expected ] || {
7212                 $LFS getstripe -R $dir
7213                 error "'$cmd' wrong: found $nums, expected $expected"
7214         }
7215
7216         expected=$onestripe
7217         cmd="$LFS find -stripe-count 1 -type f $dir"
7218         nums=$($cmd | wc -l)
7219         [ $nums -eq $expected ] || {
7220                 $LFS getstripe -R $dir
7221                 error "'$cmd' wrong: found $nums, expected $expected"
7222         }
7223
7224         cmd="$LFS find -stripe-count -2 -type f $dir"
7225         nums=$($cmd | wc -l)
7226         [ $nums -eq $expected ] || {
7227                 $LFS getstripe -R $dir
7228                 error "'$cmd' wrong: found $nums, expected $expected"
7229         }
7230
7231         expected=0
7232         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] || {
7235                 $LFS getstripe -R $dir
7236                 error "'$cmd' wrong: found $nums, expected $expected"
7237         }
7238 }
7239 run_test 56s "check lfs find -stripe-count works"
7240
7241 test_56t() { # LU-611 #LU-9369
7242         local dir=$DIR/$tdir
7243
7244         setup_56 $dir 0 $NUMDIRS
7245         for i in $(seq $NUMDIRS); do
7246                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7247         done
7248
7249         local expected=$NUMDIRS
7250         local cmd="$LFS find -S 8M $dir"
7251         local nums=$($cmd | wc -l)
7252
7253         [ $nums -eq $expected ] || {
7254                 $LFS getstripe -R $dir
7255                 error "'$cmd' wrong: found $nums, expected $expected"
7256         }
7257         rm -rf $dir
7258
7259         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7260
7261         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7262
7263         expected=$(((NUMDIRS + 1) * NUMFILES))
7264         cmd="$LFS find -stripe-size 512k -type f $dir"
7265         nums=$($cmd | wc -l)
7266         [ $nums -eq $expected ] ||
7267                 error "'$cmd' wrong: found $nums, expected $expected"
7268
7269         cmd="$LFS find -stripe-size +320k -type f $dir"
7270         nums=$($cmd | wc -l)
7271         [ $nums -eq $expected ] ||
7272                 error "'$cmd' wrong: found $nums, expected $expected"
7273
7274         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7275         cmd="$LFS find -stripe-size +200k -type f $dir"
7276         nums=$($cmd | wc -l)
7277         [ $nums -eq $expected ] ||
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279
7280         cmd="$LFS find -stripe-size -640k -type f $dir"
7281         nums=$($cmd | wc -l)
7282         [ $nums -eq $expected ] ||
7283                 error "'$cmd' wrong: found $nums, expected $expected"
7284
7285         expected=4
7286         cmd="$LFS find -stripe-size 256k -type f $dir"
7287         nums=$($cmd | wc -l)
7288         [ $nums -eq $expected ] ||
7289                 error "'$cmd' wrong: found $nums, expected $expected"
7290
7291         cmd="$LFS find -stripe-size -320k -type f $dir"
7292         nums=$($cmd | wc -l)
7293         [ $nums -eq $expected ] ||
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295
7296         expected=0
7297         cmd="$LFS find -stripe-size 1024k -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] ||
7300                 error "'$cmd' wrong: found $nums, expected $expected"
7301 }
7302 run_test 56t "check lfs find -stripe-size works"
7303
7304 test_56u() { # LU-611
7305         local dir=$DIR/$tdir
7306
7307         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7308
7309         if [[ $OSTCOUNT -gt 1 ]]; then
7310                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7311                 onestripe=4
7312         else
7313                 onestripe=0
7314         fi
7315
7316         local expected=$(((NUMDIRS + 1) * NUMFILES))
7317         local cmd="$LFS find -stripe-index 0 -type f $dir"
7318         local nums=$($cmd | wc -l)
7319
7320         [ $nums -eq $expected ] ||
7321                 error "'$cmd' wrong: found $nums, expected $expected"
7322
7323         expected=$onestripe
7324         cmd="$LFS find -stripe-index 1 -type f $dir"
7325         nums=$($cmd | wc -l)
7326         [ $nums -eq $expected ] ||
7327                 error "'$cmd' wrong: found $nums, expected $expected"
7328
7329         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7330         nums=$($cmd | wc -l)
7331         [ $nums -eq $expected ] ||
7332                 error "'$cmd' wrong: found $nums, expected $expected"
7333
7334         expected=0
7335         # This should produce an error and not return any files
7336         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7337         nums=$($cmd 2>/dev/null | wc -l)
7338         [ $nums -eq $expected ] ||
7339                 error "'$cmd' wrong: found $nums, expected $expected"
7340
7341         if [[ $OSTCOUNT -gt 1 ]]; then
7342                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7343                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7344                 nums=$($cmd | wc -l)
7345                 [ $nums -eq $expected ] ||
7346                         error "'$cmd' wrong: found $nums, expected $expected"
7347         fi
7348 }
7349 run_test 56u "check lfs find -stripe-index works"
7350
7351 test_56v() {
7352         local mdt_idx=0
7353         local dir=$DIR/$tdir
7354
7355         setup_56 $dir $NUMFILES $NUMDIRS
7356
7357         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7358         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7359
7360         for file in $($LFS find -m $UUID $dir); do
7361                 file_midx=$($LFS getstripe -m $file)
7362                 [ $file_midx -eq $mdt_idx ] ||
7363                         error "lfs find -m $UUID != getstripe -m $file_midx"
7364         done
7365 }
7366 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7367
7368 test_56wa() {
7369         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7371
7372         local dir=$DIR/$tdir
7373
7374         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7375
7376         local stripe_size=$($LFS getstripe -S -d $dir) ||
7377                 error "$LFS getstripe -S -d $dir failed"
7378         stripe_size=${stripe_size%% *}
7379
7380         local file_size=$((stripe_size * OSTCOUNT))
7381         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7382         local required_space=$((file_num * file_size))
7383         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7384                            head -n1)
7385         (( free_space >= required_space / 1024 )) ||
7386                 skip_env "need $required_space, have $free_space kbytes"
7387
7388         local dd_bs=65536
7389         local dd_count=$((file_size / dd_bs))
7390
7391         # write data into the files
7392         local i
7393         local j
7394         local file
7395
7396         for ((i = 1; i <= NUMFILES; i++ )); do
7397                 file=$dir/file$i
7398                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7399                         error "write data into $file failed"
7400         done
7401         for ((i = 1; i <= NUMDIRS; i++ )); do
7402                 for ((j = 1; j <= NUMFILES; j++ )); do
7403                         file=$dir/dir$i/file$j
7404                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7405                                 error "write data into $file failed"
7406                 done
7407         done
7408
7409         # $LFS_MIGRATE will fail if hard link migration is unsupported
7410         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7411                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7412                         error "creating links to $dir/dir1/file1 failed"
7413         fi
7414
7415         local expected=-1
7416
7417         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7418
7419         # lfs_migrate file
7420         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7421
7422         echo "$cmd"
7423         eval $cmd || error "$cmd failed"
7424
7425         check_stripe_count $dir/file1 $expected
7426
7427         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7428                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7429                 # OST 1 if it is on OST 0. This file is small enough to
7430                 # be on only one stripe.
7431                 file=$dir/migr_1_ost
7432                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7433                         error "write data into $file failed"
7434                 local obdidx=$($LFS getstripe -i $file)
7435                 local oldmd5=$(md5sum $file)
7436                 local newobdidx=0
7437
7438                 (( obdidx != 0 )) || newobdidx=1
7439                 cmd="$LFS migrate -i $newobdidx $file"
7440                 echo $cmd
7441                 eval $cmd || error "$cmd failed"
7442
7443                 local realobdix=$($LFS getstripe -i $file)
7444                 local newmd5=$(md5sum $file)
7445
7446                 (( $newobdidx == $realobdix )) ||
7447                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7448                 [[ "$oldmd5" == "$newmd5" ]] ||
7449                         error "md5sum differ: $oldmd5, $newmd5"
7450         fi
7451
7452         # lfs_migrate dir
7453         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7454         echo "$cmd"
7455         eval $cmd || error "$cmd failed"
7456
7457         for (( j = 1; j <= NUMFILES; j++ )); do
7458                 check_stripe_count $dir/dir1/file$j $expected
7459         done
7460
7461         # lfs_migrate works with lfs find
7462         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7463              $LFS_MIGRATE -y -c $expected"
7464         echo "$cmd"
7465         eval $cmd || error "$cmd failed"
7466
7467         for (( i = 2; i <= NUMFILES; i++ )); do
7468                 check_stripe_count $dir/file$i $expected
7469         done
7470         for (( i = 2; i <= NUMDIRS; i++ )); do
7471                 for (( j = 1; j <= NUMFILES; j++ )); do
7472                         check_stripe_count $dir/dir$i/file$j $expected
7473                 done
7474         done
7475 }
7476 run_test 56wa "check lfs_migrate -c stripe_count works"
7477
7478 test_56wb() {
7479         local file1=$DIR/$tdir/file1
7480         local create_pool=false
7481         local initial_pool=$($LFS getstripe -p $DIR)
7482         local pool_list=()
7483         local pool=""
7484
7485         echo -n "Creating test dir..."
7486         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7487         echo "done."
7488
7489         echo -n "Creating test file..."
7490         touch $file1 || error "cannot create file"
7491         echo "done."
7492
7493         echo -n "Detecting existing pools..."
7494         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7495
7496         if [ ${#pool_list[@]} -gt 0 ]; then
7497                 echo "${pool_list[@]}"
7498                 for thispool in "${pool_list[@]}"; do
7499                         if [[ -z "$initial_pool" ||
7500                               "$initial_pool" != "$thispool" ]]; then
7501                                 pool="$thispool"
7502                                 echo "Using existing pool '$pool'"
7503                                 break
7504                         fi
7505                 done
7506         else
7507                 echo "none detected."
7508         fi
7509         if [ -z "$pool" ]; then
7510                 pool=${POOL:-testpool}
7511                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7512                 echo -n "Creating pool '$pool'..."
7513                 create_pool=true
7514                 pool_add $pool &> /dev/null ||
7515                         error "pool_add failed"
7516                 echo "done."
7517
7518                 echo -n "Adding target to pool..."
7519                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7520                         error "pool_add_targets failed"
7521                 echo "done."
7522         fi
7523
7524         echo -n "Setting pool using -p option..."
7525         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7526                 error "migrate failed rc = $?"
7527         echo "done."
7528
7529         echo -n "Verifying test file is in pool after migrating..."
7530         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7531                 error "file was not migrated to pool $pool"
7532         echo "done."
7533
7534         echo -n "Removing test file from pool '$pool'..."
7535         # "lfs migrate $file" won't remove the file from the pool
7536         # until some striping information is changed.
7537         $LFS migrate -c 1 $file1 &> /dev/null ||
7538                 error "cannot remove from pool"
7539         [ "$($LFS getstripe -p $file1)" ] &&
7540                 error "pool still set"
7541         echo "done."
7542
7543         echo -n "Setting pool using --pool option..."
7544         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7545                 error "migrate failed rc = $?"
7546         echo "done."
7547
7548         # Clean up
7549         rm -f $file1
7550         if $create_pool; then
7551                 destroy_test_pools 2> /dev/null ||
7552                         error "destroy test pools failed"
7553         fi
7554 }
7555 run_test 56wb "check lfs_migrate pool support"
7556
7557 test_56wc() {
7558         local file1="$DIR/$tdir/$tfile"
7559         local md5
7560         local parent_ssize
7561         local parent_scount
7562         local cur_ssize
7563         local cur_scount
7564         local orig_ssize
7565         local new_scount
7566         local cur_comp
7567
7568         echo -n "Creating test dir..."
7569         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7570         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7571                 error "cannot set stripe by '-S 1M -c 1'"
7572         echo "done"
7573
7574         echo -n "Setting initial stripe for test file..."
7575         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7576                 error "cannot set stripe"
7577         cur_ssize=$($LFS getstripe -S "$file1")
7578         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7579         echo "done."
7580
7581         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7582         stack_trap "rm -f $file1"
7583         md5="$(md5sum $file1)"
7584
7585         # File currently set to -S 512K -c 1
7586
7587         # Ensure -c and -S options are rejected when -R is set
7588         echo -n "Verifying incompatible options are detected..."
7589         $LFS_MIGRATE -R -c 1 "$file1" &&
7590                 error "incompatible -R and -c options not detected"
7591         $LFS_MIGRATE -R -S 1M "$file1" &&
7592                 error "incompatible -R and -S options not detected"
7593         $LFS_MIGRATE -R -p pool "$file1" &&
7594                 error "incompatible -R and -p options not detected"
7595         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7596                 error "incompatible -R and -E options not detected"
7597         $LFS_MIGRATE -R -A "$file1" &&
7598                 error "incompatible -R and -A options not detected"
7599         $LFS_MIGRATE -A -c 1 "$file1" &&
7600                 error "incompatible -A and -c options not detected"
7601         $LFS_MIGRATE -A -S 1M "$file1" &&
7602                 error "incompatible -A and -S options not detected"
7603         $LFS_MIGRATE -A -p pool "$file1" &&
7604                 error "incompatible -A and -p options not detected"
7605         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7606                 error "incompatible -A and -E options not detected"
7607         echo "done."
7608
7609         # Ensure unrecognized options are passed through to 'lfs migrate'
7610         echo -n "Verifying -S option is passed through to lfs migrate..."
7611         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7612         cur_ssize=$($LFS getstripe -S "$file1")
7613         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7614         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7615         echo "done."
7616
7617         # File currently set to -S 1M -c 1
7618
7619         # Ensure long options are supported
7620         echo -n "Verifying long options supported..."
7621         $LFS_MIGRATE --non-block "$file1" ||
7622                 error "long option without argument not supported"
7623         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7624                 error "long option with argument not supported"
7625         cur_ssize=$($LFS getstripe -S "$file1")
7626         (( cur_ssize == 524288 )) ||
7627                 error "migrate --stripe-size $cur_ssize != 524288"
7628         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7629         echo "done."
7630
7631         # File currently set to -S 512K -c 1
7632
7633         if (( OSTCOUNT > 1 )); then
7634                 echo -n "Verifying explicit stripe count can be set..."
7635                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7636                 cur_scount=$($LFS getstripe -c "$file1")
7637                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7638                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7639                         error "file data has changed (3)"
7640                 echo "done."
7641         fi
7642
7643         # File currently set to -S 512K -c 1 or -S 512K -c 2
7644
7645         # Ensure parent striping is used if -R is set, and no stripe
7646         # count or size is specified
7647         echo -n "Setting stripe for parent directory..."
7648         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7649                 error "cannot set stripe '-S 2M -c 1'"
7650         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7651         echo "done."
7652
7653         echo -n "Verifying restripe option uses parent stripe settings..."
7654         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7655         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7656         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7657         cur_ssize=$($LFS getstripe -S "$file1")
7658         (( cur_ssize == parent_ssize )) ||
7659                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7660         cur_scount=$($LFS getstripe -c "$file1")
7661         (( cur_scount == parent_scount )) ||
7662                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7663         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7664         echo "done."
7665
7666         # File currently set to -S 1M -c 1
7667
7668         # Ensure striping is preserved if -R is not set, and no stripe
7669         # count or size is specified
7670         echo -n "Verifying striping size preserved when not specified..."
7671         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7673                 error "cannot set stripe on parent directory"
7674         $LFS_MIGRATE "$file1" || error "migrate failed"
7675         cur_ssize=$($LFS getstripe -S "$file1")
7676         (( cur_ssize == orig_ssize )) ||
7677                 error "migrate by default $cur_ssize != $orig_ssize"
7678         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7679         echo "done."
7680
7681         # Ensure file name properly detected when final option has no argument
7682         echo -n "Verifying file name properly detected..."
7683         $LFS_MIGRATE "$file1" ||
7684                 error "file name interpreted as option argument"
7685         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7686         echo "done."
7687
7688         # Ensure PFL arguments are passed through properly
7689         echo -n "Verifying PFL options passed through..."
7690         new_scount=$(((OSTCOUNT + 1) / 2))
7691         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7692                 error "migrate PFL arguments failed"
7693         cur_comp=$($LFS getstripe --comp-count $file1)
7694         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7695         cur_scount=$($LFS getstripe --stripe-count $file1)
7696         (( cur_scount == new_scount)) ||
7697                 error "PFL stripe count $cur_scount != $new_scount"
7698         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7699         echo "done."
7700 }
7701 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7702
7703 test_56wd() {
7704         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7705
7706         local file1=$DIR/$tdir/$tfile
7707
7708         echo -n "Creating test dir..."
7709         test_mkdir $DIR/$tdir || error "cannot create dir"
7710         echo "done."
7711
7712         echo -n "Creating test file..."
7713         echo "$tfile" > $file1
7714         echo "done."
7715
7716         # Ensure 'lfs migrate' will fail by using a non-existent option,
7717         # and make sure rsync is not called to recover
7718         echo -n "Make sure --no-rsync option works..."
7719         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7720                 grep -q 'refusing to fall back to rsync' ||
7721                 error "rsync was called with --no-rsync set"
7722         echo "done."
7723
7724         # Ensure rsync is called without trying 'lfs migrate' first
7725         echo -n "Make sure --rsync option works..."
7726         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7727                 grep -q 'falling back to rsync' &&
7728                 error "lfs migrate was called with --rsync set"
7729         echo "done."
7730 }
7731 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7732
7733 test_56we() {
7734         local td=$DIR/$tdir
7735         local tf=$td/$tfile
7736
7737         test_mkdir $td || error "cannot create $td"
7738         touch $tf || error "cannot touch $tf"
7739
7740         echo -n "Make sure --non-direct|-D works..."
7741         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7742                 grep -q "lfs migrate --non-direct" ||
7743                 error "--non-direct option cannot work correctly"
7744         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7745                 grep -q "lfs migrate -D" ||
7746                 error "-D option cannot work correctly"
7747         echo "done."
7748 }
7749 run_test 56we "check lfs_migrate --non-direct|-D support"
7750
7751 test_56x() {
7752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7753         check_swap_layouts_support
7754
7755         local dir=$DIR/$tdir
7756         local ref1=/etc/passwd
7757         local file1=$dir/file1
7758
7759         test_mkdir $dir || error "creating dir $dir"
7760         $LFS setstripe -c 2 $file1
7761         cp $ref1 $file1
7762         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7763         stripe=$($LFS getstripe -c $file1)
7764         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7765         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7766
7767         # clean up
7768         rm -f $file1
7769 }
7770 run_test 56x "lfs migration support"
7771
7772 test_56xa() {
7773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7774         check_swap_layouts_support
7775
7776         local dir=$DIR/$tdir/$testnum
7777
7778         test_mkdir -p $dir
7779
7780         local ref1=/etc/passwd
7781         local file1=$dir/file1
7782
7783         $LFS setstripe -c 2 $file1
7784         cp $ref1 $file1
7785         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7786
7787         local stripe=$($LFS getstripe -c $file1)
7788
7789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7791
7792         # clean up
7793         rm -f $file1
7794 }
7795 run_test 56xa "lfs migration --block support"
7796
7797 check_migrate_links() {
7798         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7799         local dir="$1"
7800         local file1="$dir/file1"
7801         local begin="$2"
7802         local count="$3"
7803         local runas="$4"
7804         local total_count=$(($begin + $count - 1))
7805         local symlink_count=10
7806         local uniq_count=10
7807
7808         if [ ! -f "$file1" ]; then
7809                 echo -n "creating initial file..."
7810                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7811                         error "cannot setstripe initial file"
7812                 echo "done"
7813
7814                 echo -n "creating symlinks..."
7815                 for s in $(seq 1 $symlink_count); do
7816                         ln -s "$file1" "$dir/slink$s" ||
7817                                 error "cannot create symlinks"
7818                 done
7819                 echo "done"
7820
7821                 echo -n "creating nonlinked files..."
7822                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7823                         error "cannot create nonlinked files"
7824                 echo "done"
7825         fi
7826
7827         # create hard links
7828         if [ ! -f "$dir/file$total_count" ]; then
7829                 echo -n "creating hard links $begin:$total_count..."
7830                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7831                         /dev/null || error "cannot create hard links"
7832                 echo "done"
7833         fi
7834
7835         echo -n "checking number of hard links listed in xattrs..."
7836         local fid=$($LFS getstripe -F "$file1")
7837         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7838
7839         echo "${#paths[*]}"
7840         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7841                         skip "hard link list has unexpected size, skipping test"
7842         fi
7843         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7844                         error "link names should exceed xattrs size"
7845         fi
7846
7847         echo -n "migrating files..."
7848         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7849         local rc=$?
7850         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7851         echo "done"
7852
7853         # make sure all links have been properly migrated
7854         echo -n "verifying files..."
7855         fid=$($LFS getstripe -F "$file1") ||
7856                 error "cannot get fid for file $file1"
7857         for i in $(seq 2 $total_count); do
7858                 local fid2=$($LFS getstripe -F $dir/file$i)
7859
7860                 [ "$fid2" == "$fid" ] ||
7861                         error "migrated hard link has mismatched FID"
7862         done
7863
7864         # make sure hard links were properly detected, and migration was
7865         # performed only once for the entire link set; nonlinked files should
7866         # also be migrated
7867         local actual=$(grep -c 'done' <<< "$migrate_out")
7868         local expected=$(($uniq_count + 1))
7869
7870         [ "$actual" -eq  "$expected" ] ||
7871                 error "hard links individually migrated ($actual != $expected)"
7872
7873         # make sure the correct number of hard links are present
7874         local hardlinks=$(stat -c '%h' "$file1")
7875
7876         [ $hardlinks -eq $total_count ] ||
7877                 error "num hard links $hardlinks != $total_count"
7878         echo "done"
7879
7880         return 0
7881 }
7882
7883 test_56xb() {
7884         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7885                 skip "Need MDS version at least 2.10.55"
7886
7887         local dir="$DIR/$tdir"
7888
7889         test_mkdir "$dir" || error "cannot create dir $dir"
7890
7891         echo "testing lfs migrate mode when all links fit within xattrs"
7892         check_migrate_links "$dir" 2 99
7893
7894         echo "testing rsync mode when all links fit within xattrs"
7895         check_migrate_links --rsync "$dir" 2 99
7896
7897         echo "testing lfs migrate mode when all links do not fit within xattrs"
7898         check_migrate_links "$dir" 101 100
7899
7900         echo "testing rsync mode when all links do not fit within xattrs"
7901         check_migrate_links --rsync "$dir" 101 100
7902
7903         chown -R $RUNAS_ID $dir
7904         echo "testing non-root lfs migrate mode when not all links are in xattr"
7905         check_migrate_links "$dir" 101 100 "$RUNAS"
7906
7907         # clean up
7908         rm -rf $dir
7909 }
7910 run_test 56xb "lfs migration hard link support"
7911
7912 test_56xc() {
7913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7914
7915         local dir="$DIR/$tdir"
7916
7917         test_mkdir "$dir" || error "cannot create dir $dir"
7918
7919         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7920         echo -n "Setting initial stripe for 20MB test file..."
7921         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7922                 error "cannot setstripe 20MB file"
7923         echo "done"
7924         echo -n "Sizing 20MB test file..."
7925         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7926         echo "done"
7927         echo -n "Verifying small file autostripe count is 1..."
7928         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7929                 error "cannot migrate 20MB file"
7930         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7931                 error "cannot get stripe for $dir/20mb"
7932         [ $stripe_count -eq 1 ] ||
7933                 error "unexpected stripe count $stripe_count for 20MB file"
7934         rm -f "$dir/20mb"
7935         echo "done"
7936
7937         # Test 2: File is small enough to fit within the available space on
7938         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7939         # have at least an additional 1KB for each desired stripe for test 3
7940         echo -n "Setting stripe for 1GB test file..."
7941         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7942         echo "done"
7943         echo -n "Sizing 1GB test file..."
7944         # File size is 1GB + 3KB
7945         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7946         echo "done"
7947
7948         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7949         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7950         if (( avail > 524288 * OSTCOUNT )); then
7951                 echo -n "Migrating 1GB file..."
7952                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7953                         error "cannot migrate 1GB file"
7954                 echo "done"
7955                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7956                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7957                         error "cannot getstripe for 1GB file"
7958                 [ $stripe_count -eq 2 ] ||
7959                         error "unexpected stripe count $stripe_count != 2"
7960                 echo "done"
7961         fi
7962
7963         # Test 3: File is too large to fit within the available space on
7964         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7965         if [ $OSTCOUNT -ge 3 ]; then
7966                 # The required available space is calculated as
7967                 # file size (1GB + 3KB) / OST count (3).
7968                 local kb_per_ost=349526
7969
7970                 echo -n "Migrating 1GB file with limit..."
7971                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7972                         error "cannot migrate 1GB file with limit"
7973                 echo "done"
7974
7975                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7976                 echo -n "Verifying 1GB autostripe count with limited space..."
7977                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7978                         error "unexpected stripe count $stripe_count (min 3)"
7979                 echo "done"
7980         fi
7981
7982         # clean up
7983         rm -rf $dir
7984 }
7985 run_test 56xc "lfs migration autostripe"
7986
7987 test_56xd() {
7988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7989
7990         local dir=$DIR/$tdir
7991         local f_mgrt=$dir/$tfile.mgrt
7992         local f_yaml=$dir/$tfile.yaml
7993         local f_copy=$dir/$tfile.copy
7994         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7995         local layout_copy="-c 2 -S 2M -i 1"
7996         local yamlfile=$dir/yamlfile
7997         local layout_before;
7998         local layout_after;
7999
8000         test_mkdir "$dir" || error "cannot create dir $dir"
8001         $LFS setstripe $layout_yaml $f_yaml ||
8002                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8003         $LFS getstripe --yaml $f_yaml > $yamlfile
8004         $LFS setstripe $layout_copy $f_copy ||
8005                 error "cannot setstripe $f_copy with layout $layout_copy"
8006         touch $f_mgrt
8007         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8008
8009         # 1. test option --yaml
8010         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8011                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8012         layout_before=$(get_layout_param $f_yaml)
8013         layout_after=$(get_layout_param $f_mgrt)
8014         [ "$layout_after" == "$layout_before" ] ||
8015                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8016
8017         # 2. test option --copy
8018         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8019                 error "cannot migrate $f_mgrt with --copy $f_copy"
8020         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8021         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8022         [ "$layout_after" == "$layout_before" ] ||
8023                 error "lfs_migrate --copy: $layout_after != $layout_before"
8024 }
8025 run_test 56xd "check lfs_migrate --yaml and --copy support"
8026
8027 test_56xe() {
8028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8029
8030         local dir=$DIR/$tdir
8031         local f_comp=$dir/$tfile
8032         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8033         local layout_before=""
8034         local layout_after=""
8035
8036         test_mkdir "$dir" || error "cannot create dir $dir"
8037         $LFS setstripe $layout $f_comp ||
8038                 error "cannot setstripe $f_comp with layout $layout"
8039         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8040         dd if=/dev/zero of=$f_comp bs=1M count=4
8041
8042         # 1. migrate a comp layout file by lfs_migrate
8043         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8044         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8045         [ "$layout_before" == "$layout_after" ] ||
8046                 error "lfs_migrate: $layout_before != $layout_after"
8047
8048         # 2. migrate a comp layout file by lfs migrate
8049         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8050         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8051         [ "$layout_before" == "$layout_after" ] ||
8052                 error "lfs migrate: $layout_before != $layout_after"
8053 }
8054 run_test 56xe "migrate a composite layout file"
8055
8056 test_56xf() {
8057         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8058
8059         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8060                 skip "Need server version at least 2.13.53"
8061
8062         local dir=$DIR/$tdir
8063         local f_comp=$dir/$tfile
8064         local layout="-E 1M -c1 -E -1 -c2"
8065         local fid_before=""
8066         local fid_after=""
8067
8068         test_mkdir "$dir" || error "cannot create dir $dir"
8069         $LFS setstripe $layout $f_comp ||
8070                 error "cannot setstripe $f_comp with layout $layout"
8071         fid_before=$($LFS getstripe --fid $f_comp)
8072         dd if=/dev/zero of=$f_comp bs=1M count=4
8073
8074         # 1. migrate a comp layout file to a comp layout
8075         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8076         fid_after=$($LFS getstripe --fid $f_comp)
8077         [ "$fid_before" == "$fid_after" ] ||
8078                 error "comp-to-comp migrate: $fid_before != $fid_after"
8079
8080         # 2. migrate a comp layout file to a plain layout
8081         $LFS migrate -c2 $f_comp ||
8082                 error "cannot migrate $f_comp by lfs migrate"
8083         fid_after=$($LFS getstripe --fid $f_comp)
8084         [ "$fid_before" == "$fid_after" ] ||
8085                 error "comp-to-plain migrate: $fid_before != $fid_after"
8086
8087         # 3. migrate a plain layout file to a comp layout
8088         $LFS migrate $layout $f_comp ||
8089                 error "cannot migrate $f_comp by lfs migrate"
8090         fid_after=$($LFS getstripe --fid $f_comp)
8091         [ "$fid_before" == "$fid_after" ] ||
8092                 error "plain-to-comp migrate: $fid_before != $fid_after"
8093 }
8094 run_test 56xf "FID is not lost during migration of a composite layout file"
8095
8096 check_file_ost_range() {
8097         local file="$1"
8098         shift
8099         local range="$*"
8100         local -a file_range
8101         local idx
8102
8103         file_range=($($LFS getstripe -y "$file" |
8104                 awk '/l_ost_idx:/ { print $NF }'))
8105
8106         if [[ "${#file_range[@]}" = 0 ]]; then
8107                 echo "No osts found for $file"
8108                 return 1
8109         fi
8110
8111         for idx in "${file_range[@]}"; do
8112                 [[ " $range " =~ " $idx " ]] ||
8113                         return 1
8114         done
8115
8116         return 0
8117 }
8118
8119 sub_test_56xg() {
8120         local stripe_opt="$1"
8121         local pool="$2"
8122         shift 2
8123         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8124
8125         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8126                 error "Fail to migrate $tfile on $pool"
8127         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8128                 error "$tfile is not in pool $pool"
8129         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8130                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8131 }
8132
8133 test_56xg() {
8134         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8135         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8136         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8137                 skip "Need MDS version newer than 2.14.52"
8138
8139         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8140         local -a pool_ranges=("0 0" "1 1" "0 1")
8141
8142         # init pools
8143         for i in "${!pool_names[@]}"; do
8144                 pool_add ${pool_names[$i]} ||
8145                         error "pool_add failed (pool: ${pool_names[$i]})"
8146                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8147                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8148         done
8149
8150         # init the file to migrate
8151         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8152                 error "Unable to create $tfile on OST1"
8153         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8154                 error "Unable to write on $tfile"
8155
8156         echo "1. migrate $tfile on pool ${pool_names[0]}"
8157         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8158
8159         echo "2. migrate $tfile on pool ${pool_names[2]}"
8160         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8161
8162         echo "3. migrate $tfile on pool ${pool_names[1]}"
8163         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8164
8165         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8166         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8167         echo
8168
8169         # Clean pools
8170         destroy_test_pools ||
8171                 error "pool_destroy failed"
8172 }
8173 run_test 56xg "lfs migrate pool support"
8174
8175 test_56xh() {
8176         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8177
8178         local size_mb=25
8179         local file1=$DIR/$tfile
8180         local tmp1=$TMP/$tfile.tmp
8181
8182         $LFS setstripe -c 2 $file1
8183
8184         stack_trap "rm -f $file1 $tmp1"
8185         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8186                         error "error creating $tmp1"
8187         ls -lsh $tmp1
8188         cp $tmp1 $file1
8189
8190         local start=$SECONDS
8191
8192         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8193                 error "migrate failed rc = $?"
8194
8195         local elapsed=$((SECONDS - start))
8196
8197         # with 1MB/s, elapsed should equal size_mb
8198         (( elapsed >= size_mb * 95 / 100 )) ||
8199                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8200
8201         (( elapsed <= size_mb * 120 / 100 )) ||
8202                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8203
8204         (( elapsed <= size_mb * 350 / 100 )) ||
8205                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8206
8207         stripe=$($LFS getstripe -c $file1)
8208         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8209         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8210
8211         # Clean up file (since it is multiple MB)
8212         rm -f $file1 $tmp1
8213 }
8214 run_test 56xh "lfs migrate bandwidth limitation support"
8215
8216 test_56xi() {
8217         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8218         verify_yaml_available || skip_env "YAML verification not installed"
8219
8220         local size_mb=5
8221         local file1=$DIR/$tfile.1
8222         local file2=$DIR/$tfile.2
8223         local file3=$DIR/$tfile.3
8224         local output_file=$DIR/$tfile.out
8225         local tmp1=$TMP/$tfile.tmp
8226
8227         $LFS setstripe -c 2 $file1
8228         $LFS setstripe -c 2 $file2
8229         $LFS setstripe -c 2 $file3
8230
8231         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8232         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8233                         error "error creating $tmp1"
8234         ls -lsh $tmp1
8235         cp $tmp1 $file1
8236         cp $tmp1 $file2
8237         cp $tmp1 $file3
8238
8239         $LFS migrate --stats --stats-interval=1 \
8240                 -c 1 $file1 $file2 $file3 1> $output_file ||
8241                 error "migrate failed rc = $?"
8242
8243         cat $output_file
8244         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8245
8246         # Clean up file (since it is multiple MB)
8247         rm -f $file1 $file2 $file3 $tmp1 $output_file
8248 }
8249 run_test 56xi "lfs migrate stats support"
8250
8251 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8252         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8253
8254         local file=$DIR/$tfile
8255         local linkdir=$DIR/$tdir
8256
8257         test_mkdir $linkdir || error "fail to create $linkdir"
8258         $LFS setstripe -i 0 -c 1 -S1M $file
8259         dd if=/dev/urandom of=$file bs=1M count=10 ||
8260                 error "fail to create $file"
8261
8262         # Create file links
8263         local cpts
8264         local threads_max
8265         local nlinks
8266
8267         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8268         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8269         (( nlinks = thread_max * 3 / 2 / cpts))
8270
8271         echo "create $nlinks hard links of $file"
8272         createmany -l $file $linkdir/link $nlinks
8273
8274         # Parallel migrates (should not block)
8275         local i
8276         for ((i = 0; i < nlinks; i++)); do
8277                 echo $linkdir/link$i
8278         done | xargs -n1 -P $nlinks $LFS migrate -c2
8279
8280         local stripe_count
8281         stripe_count=$($LFS getstripe -c $file) ||
8282                 error "fail to get stripe count on $file"
8283
8284         ((stripe_count == 2)) ||
8285                 error "fail to migrate $file (stripe_count = $stripe_count)"
8286 }
8287 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8288
8289 test_56y() {
8290         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8291                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8292
8293         local res=""
8294         local dir=$DIR/$tdir
8295         local f1=$dir/file1
8296         local f2=$dir/file2
8297
8298         test_mkdir -p $dir || error "creating dir $dir"
8299         touch $f1 || error "creating std file $f1"
8300         $MULTIOP $f2 H2c || error "creating released file $f2"
8301
8302         # a directory can be raid0, so ask only for files
8303         res=$($LFS find $dir -L raid0 -type f | wc -l)
8304         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8305
8306         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8307         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8308
8309         # only files can be released, so no need to force file search
8310         res=$($LFS find $dir -L released)
8311         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8312
8313         res=$($LFS find $dir -type f \! -L released)
8314         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8315 }
8316 run_test 56y "lfs find -L raid0|released"
8317
8318 test_56z() { # LU-4824
8319         # This checks to make sure 'lfs find' continues after errors
8320         # There are two classes of errors that should be caught:
8321         # - If multiple paths are provided, all should be searched even if one
8322         #   errors out
8323         # - If errors are encountered during the search, it should not terminate
8324         #   early
8325         local dir=$DIR/$tdir
8326         local i
8327
8328         test_mkdir $dir
8329         for i in d{0..9}; do
8330                 test_mkdir $dir/$i
8331                 touch $dir/$i/$tfile
8332         done
8333         $LFS find $DIR/non_existent_dir $dir &&
8334                 error "$LFS find did not return an error"
8335         # Make a directory unsearchable. This should NOT be the last entry in
8336         # directory order.  Arbitrarily pick the 6th entry
8337         chmod 700 $($LFS find $dir -type d | sed '6!d')
8338
8339         $RUNAS $LFS find $DIR/non_existent $dir
8340         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8341
8342         # The user should be able to see 10 directories and 9 files
8343         (( count == 19 )) ||
8344                 error "$LFS find found $count != 19 entries after error"
8345 }
8346 run_test 56z "lfs find should continue after an error"
8347
8348 test_56aa() { # LU-5937
8349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8350
8351         local dir=$DIR/$tdir
8352
8353         mkdir $dir
8354         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8355
8356         createmany -o $dir/striped_dir/${tfile}- 1024
8357         local dirs=$($LFS find --size +8k $dir/)
8358
8359         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8360 }
8361 run_test 56aa "lfs find --size under striped dir"
8362
8363 test_56ab() { # LU-10705
8364         test_mkdir $DIR/$tdir
8365         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8366         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8367         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8368         # Flush writes to ensure valid blocks.  Need to be more thorough for
8369         # ZFS, since blocks are not allocated/returned to client immediately.
8370         sync_all_data
8371         wait_zfs_commit ost1 2
8372         cancel_lru_locks osc
8373         ls -ls $DIR/$tdir
8374
8375         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8376
8377         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8378
8379         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8380         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8381
8382         rm -f $DIR/$tdir/$tfile.[123]
8383 }
8384 run_test 56ab "lfs find --blocks"
8385
8386 # LU-11188
8387 test_56aca() {
8388         local dir="$DIR/$tdir"
8389         local perms=(001 002 003 004 005 006 007
8390                      010 020 030 040 050 060 070
8391                      100 200 300 400 500 600 700
8392                      111 222 333 444 555 666 777)
8393         local perm_minus=(8 8 4 8 4 4 2
8394                           8 8 4 8 4 4 2
8395                           8 8 4 8 4 4 2
8396                           4 4 2 4 2 2 1)
8397         local perm_slash=(8  8 12  8 12 12 14
8398                           8  8 12  8 12 12 14
8399                           8  8 12  8 12 12 14
8400                          16 16 24 16 24 24 28)
8401
8402         test_mkdir "$dir"
8403         for perm in ${perms[*]}; do
8404                 touch "$dir/$tfile.$perm"
8405                 chmod $perm "$dir/$tfile.$perm"
8406         done
8407
8408         for ((i = 0; i < ${#perms[*]}; i++)); do
8409                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8410                 (( $num == 1 )) ||
8411                         error "lfs find -perm ${perms[i]}:"\
8412                               "$num != 1"
8413
8414                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8415                 (( $num == ${perm_minus[i]} )) ||
8416                         error "lfs find -perm -${perms[i]}:"\
8417                               "$num != ${perm_minus[i]}"
8418
8419                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8420                 (( $num == ${perm_slash[i]} )) ||
8421                         error "lfs find -perm /${perms[i]}:"\
8422                               "$num != ${perm_slash[i]}"
8423         done
8424 }
8425 run_test 56aca "check lfs find -perm with octal representation"
8426
8427 test_56acb() {
8428         local dir=$DIR/$tdir
8429         # p is the permission of write and execute for user, group and other
8430         # without the umask. It is used to test +wx.
8431         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8432         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8433         local symbolic=(+t  a+t u+t g+t o+t
8434                         g+s u+s o+s +s o+sr
8435                         o=r,ug+o,u+w
8436                         u+ g+ o+ a+ ugo+
8437                         u- g- o- a- ugo-
8438                         u= g= o= a= ugo=
8439                         o=r,ug+o,u+w u=r,a+u,u+w
8440                         g=r,ugo=g,u+w u+x,+X +X
8441                         u+x,u+X u+X u+x,g+X o+r,+X
8442                         u+x,go+X +wx +rwx)
8443
8444         test_mkdir $dir
8445         for perm in ${perms[*]}; do
8446                 touch "$dir/$tfile.$perm"
8447                 chmod $perm "$dir/$tfile.$perm"
8448         done
8449
8450         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8451                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8452
8453                 (( $num == 1 )) ||
8454                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8455         done
8456 }
8457 run_test 56acb "check lfs find -perm with symbolic representation"
8458
8459 test_56acc() {
8460         local dir=$DIR/$tdir
8461         local tests="17777 787 789 abcd
8462                 ug=uu ug=a ug=gu uo=ou urw
8463                 u+xg+x a=r,u+x,"
8464
8465         test_mkdir $dir
8466         for err in $tests; do
8467                 if $LFS find $dir -perm $err 2>/dev/null; then
8468                         error "lfs find -perm $err: parsing should have failed"
8469                 fi
8470         done
8471 }
8472 run_test 56acc "check parsing error for lfs find -perm"
8473
8474 test_56ba() {
8475         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8476                 skip "Need MDS version at least 2.10.50"
8477
8478         # Create composite files with one component
8479         local dir=$DIR/$tdir
8480
8481         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8482         # Create composite files with three components
8483         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8484         # Create non-composite files
8485         createmany -o $dir/${tfile}- 10
8486
8487         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8488
8489         [[ $nfiles == 10 ]] ||
8490                 error "lfs find -E 1M found $nfiles != 10 files"
8491
8492         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8493         [[ $nfiles == 25 ]] ||
8494                 error "lfs find ! -E 1M found $nfiles != 25 files"
8495
8496         # All files have a component that starts at 0
8497         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8498         [[ $nfiles == 35 ]] ||
8499                 error "lfs find --component-start 0 - $nfiles != 35 files"
8500
8501         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8502         [[ $nfiles == 15 ]] ||
8503                 error "lfs find --component-start 2M - $nfiles != 15 files"
8504
8505         # All files created here have a componenet that does not starts at 2M
8506         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8507         [[ $nfiles == 35 ]] ||
8508                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8509
8510         # Find files with a specified number of components
8511         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8512         [[ $nfiles == 15 ]] ||
8513                 error "lfs find --component-count 3 - $nfiles != 15 files"
8514
8515         # Remember non-composite files have a component count of zero
8516         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8517         [[ $nfiles == 10 ]] ||
8518                 error "lfs find --component-count 0 - $nfiles != 10 files"
8519
8520         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8521         [[ $nfiles == 20 ]] ||
8522                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8523
8524         # All files have a flag called "init"
8525         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8526         [[ $nfiles == 35 ]] ||
8527                 error "lfs find --component-flags init - $nfiles != 35 files"
8528
8529         # Multi-component files will have a component not initialized
8530         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8531         [[ $nfiles == 15 ]] ||
8532                 error "lfs find !--component-flags init - $nfiles != 15 files"
8533
8534         rm -rf $dir
8535
8536 }
8537 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8538
8539 test_56ca() {
8540         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8541                 skip "Need MDS version at least 2.10.57"
8542
8543         local td=$DIR/$tdir
8544         local tf=$td/$tfile
8545         local dir
8546         local nfiles
8547         local cmd
8548         local i
8549         local j
8550
8551         # create mirrored directories and mirrored files
8552         mkdir $td || error "mkdir $td failed"
8553         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8554         createmany -o $tf- 10 || error "create $tf- failed"
8555
8556         for i in $(seq 2); do
8557                 dir=$td/dir$i
8558                 mkdir $dir || error "mkdir $dir failed"
8559                 $LFS mirror create -N$((3 + i)) $dir ||
8560                         error "create mirrored dir $dir failed"
8561                 createmany -o $dir/$tfile- 10 ||
8562                         error "create $dir/$tfile- failed"
8563         done
8564
8565         # change the states of some mirrored files
8566         echo foo > $tf-6
8567         for i in $(seq 2); do
8568                 dir=$td/dir$i
8569                 for j in $(seq 4 9); do
8570                         echo foo > $dir/$tfile-$j
8571                 done
8572         done
8573
8574         # find mirrored files with specific mirror count
8575         cmd="$LFS find --mirror-count 3 --type f $td"
8576         nfiles=$($cmd | wc -l)
8577         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8578
8579         cmd="$LFS find ! --mirror-count 3 --type f $td"
8580         nfiles=$($cmd | wc -l)
8581         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8582
8583         cmd="$LFS find --mirror-count +2 --type f $td"
8584         nfiles=$($cmd | wc -l)
8585         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8586
8587         cmd="$LFS find --mirror-count -6 --type f $td"
8588         nfiles=$($cmd | wc -l)
8589         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8590
8591         # find mirrored files with specific file state
8592         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8593         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8594
8595         cmd="$LFS find --mirror-state=ro --type f $td"
8596         nfiles=$($cmd | wc -l)
8597         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8598
8599         cmd="$LFS find ! --mirror-state=ro --type f $td"
8600         nfiles=$($cmd | wc -l)
8601         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8602
8603         cmd="$LFS find --mirror-state=wp --type f $td"
8604         nfiles=$($cmd | wc -l)
8605         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8606
8607         cmd="$LFS find ! --mirror-state=sp --type f $td"
8608         nfiles=$($cmd | wc -l)
8609         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8610 }
8611 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8612
8613 test_56da() { # LU-14179
8614         local path=$DIR/$tdir
8615
8616         test_mkdir $path
8617         cd $path
8618
8619         local longdir=$(str_repeat 'a' 255)
8620
8621         for i in {1..15}; do
8622                 path=$path/$longdir
8623                 test_mkdir $longdir
8624                 cd $longdir
8625         done
8626
8627         local len=${#path}
8628         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8629
8630         test_mkdir $lastdir
8631         cd $lastdir
8632         # PATH_MAX-1
8633         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8634
8635         # NAME_MAX
8636         touch $(str_repeat 'f' 255)
8637
8638         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8639                 error "lfs find reported an error"
8640
8641         rm -rf $DIR/$tdir
8642 }
8643 run_test 56da "test lfs find with long paths"
8644
8645 test_56ea() { #LU-10378
8646         local path=$DIR/$tdir
8647         local pool=$TESTNAME
8648
8649         # Create ost pool
8650         pool_add $pool || error "pool_add $pool failed"
8651         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8652                 error "adding targets to $pool failed"
8653
8654         # Set default pool on directory before creating file
8655         mkdir $path || error "mkdir $path failed"
8656         $LFS setstripe -p $pool $path ||
8657                 error "set OST pool on $pool failed"
8658         touch $path/$tfile || error "touch $path/$tfile failed"
8659
8660         # Compare basic file attributes from -printf and stat
8661         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8662         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8663
8664         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8665                 error "Attrs from lfs find and stat don't match"
8666
8667         # Compare Lustre attributes from lfs find and lfs getstripe
8668         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8669         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8670         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8671         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8672         local fpool=$($LFS getstripe --pool $path/$tfile)
8673         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8674
8675         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8676                 error "Attrs from lfs find and lfs getstripe don't match"
8677
8678         # Verify behavior for unknown escape/format sequences
8679         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8680
8681         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8682                 error "Escape/format codes don't match"
8683 }
8684 run_test 56ea "test lfs find -printf option"
8685
8686 test_56eb() {
8687         local dir=$DIR/$tdir
8688         local subdir_1=$dir/subdir_1
8689
8690         test_mkdir -p $subdir_1
8691         ln -s subdir_1 $dir/link_1
8692
8693         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8694                 error "symlink is not followed"
8695
8696         $LFS getstripe --no-follow $dir |
8697                 grep "^$dir/link_1 has no stripe info$" ||
8698                 error "symlink should not have stripe info"
8699
8700         touch $dir/testfile
8701         ln -s testfile $dir/file_link_2
8702
8703         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8704                 error "symlink is not followed"
8705
8706         $LFS getstripe --no-follow $dir |
8707                 grep "^$dir/file_link_2 has no stripe info$" ||
8708                 error "symlink should not have stripe info"
8709 }
8710 run_test 56eb "check lfs getstripe on symlink"
8711
8712 test_56ec() {
8713         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8714         local dir=$DIR/$tdir
8715         local srcfile=$dir/srcfile
8716         local srcyaml=$dir/srcyaml
8717         local destfile=$dir/destfile
8718
8719         test_mkdir -p $dir
8720
8721         $LFS setstripe -i 1 $srcfile
8722         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8723         # if the setstripe yaml parsing fails for any reason, the command can
8724         # randomly assign the correct OST index, leading to an erroneous
8725         # success. but the chance of false success is low enough that a
8726         # regression should still be quickly caught.
8727         $LFS setstripe --yaml=$srcyaml $destfile
8728
8729         local srcindex=$($LFS getstripe -i $srcfile)
8730         local destindex=$($LFS getstripe -i $destfile)
8731
8732         if [[ ! $srcindex -eq $destindex ]]; then
8733                 error "setstripe did not set OST index correctly"
8734         fi
8735 }
8736 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8737
8738 test_57a() {
8739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8740         # note test will not do anything if MDS is not local
8741         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8742                 skip_env "ldiskfs only test"
8743         fi
8744         remote_mds_nodsh && skip "remote MDS with nodsh"
8745
8746         local MNTDEV="osd*.*MDT*.mntdev"
8747         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8748         [ -z "$DEV" ] && error "can't access $MNTDEV"
8749         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8750                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8751                         error "can't access $DEV"
8752                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8753                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8754                 rm $TMP/t57a.dump
8755         done
8756 }
8757 run_test 57a "verify MDS filesystem created with large inodes =="
8758
8759 test_57b() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8762                 skip_env "ldiskfs only test"
8763         fi
8764         remote_mds_nodsh && skip "remote MDS with nodsh"
8765
8766         local dir=$DIR/$tdir
8767         local filecount=100
8768         local file1=$dir/f1
8769         local fileN=$dir/f$filecount
8770
8771         rm -rf $dir || error "removing $dir"
8772         test_mkdir -c1 $dir
8773         local mdtidx=$($LFS getstripe -m $dir)
8774         local mdtname=MDT$(printf %04x $mdtidx)
8775         local facet=mds$((mdtidx + 1))
8776
8777         echo "mcreating $filecount files"
8778         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8779
8780         # verify that files do not have EAs yet
8781         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8782                 error "$file1 has an EA"
8783         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8784                 error "$fileN has an EA"
8785
8786         sync
8787         sleep 1
8788         df $dir  #make sure we get new statfs data
8789         local mdsfree=$(do_facet $facet \
8790                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8791         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8792         local file
8793
8794         echo "opening files to create objects/EAs"
8795         for file in $(seq -f $dir/f%g 1 $filecount); do
8796                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8797                         error "opening $file"
8798         done
8799
8800         # verify that files have EAs now
8801         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8802         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8803
8804         sleep 1  #make sure we get new statfs data
8805         df $dir
8806         local mdsfree2=$(do_facet $facet \
8807                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8808         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8809
8810         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8811                 if [ "$mdsfree" != "$mdsfree2" ]; then
8812                         error "MDC before $mdcfree != after $mdcfree2"
8813                 else
8814                         echo "MDC before $mdcfree != after $mdcfree2"
8815                         echo "unable to confirm if MDS has large inodes"
8816                 fi
8817         fi
8818         rm -rf $dir
8819 }
8820 run_test 57b "default LOV EAs are stored inside large inodes ==="
8821
8822 test_58() {
8823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8824         [ -z "$(which wiretest 2>/dev/null)" ] &&
8825                         skip_env "could not find wiretest"
8826
8827         wiretest
8828 }
8829 run_test 58 "verify cross-platform wire constants =============="
8830
8831 test_59() {
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833
8834         echo "touch 130 files"
8835         createmany -o $DIR/f59- 130
8836         echo "rm 130 files"
8837         unlinkmany $DIR/f59- 130
8838         sync
8839         # wait for commitment of removal
8840         wait_delete_completed
8841 }
8842 run_test 59 "verify cancellation of llog records async ========="
8843
8844 TEST60_HEAD="test_60 run $RANDOM"
8845 test_60a() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847         remote_mgs_nodsh && skip "remote MGS with nodsh"
8848         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8849                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8850                         skip_env "missing subtest run-llog.sh"
8851
8852         log "$TEST60_HEAD - from kernel mode"
8853         do_facet mgs "$LCTL dk > /dev/null"
8854         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8855         do_facet mgs $LCTL dk > $TMP/$tfile
8856
8857         # LU-6388: test llog_reader
8858         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8859         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8860         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8861                         skip_env "missing llog_reader"
8862         local fstype=$(facet_fstype mgs)
8863         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8864                 skip_env "Only for ldiskfs or zfs type mgs"
8865
8866         local mntpt=$(facet_mntpt mgs)
8867         local mgsdev=$(mgsdevname 1)
8868         local fid_list
8869         local fid
8870         local rec_list
8871         local rec
8872         local rec_type
8873         local obj_file
8874         local path
8875         local seq
8876         local oid
8877         local pass=true
8878
8879         #get fid and record list
8880         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8881                 tail -n 4))
8882         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8883                 tail -n 4))
8884         #remount mgs as ldiskfs or zfs type
8885         stop mgs || error "stop mgs failed"
8886         mount_fstype mgs || error "remount mgs failed"
8887         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8888                 fid=${fid_list[i]}
8889                 rec=${rec_list[i]}
8890                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8891                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8892                 oid=$((16#$oid))
8893
8894                 case $fstype in
8895                         ldiskfs )
8896                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8897                         zfs )
8898                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8899                 esac
8900                 echo "obj_file is $obj_file"
8901                 do_facet mgs $llog_reader $obj_file
8902
8903                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8904                         awk '{ print $3 }' | sed -e "s/^type=//g")
8905                 if [ $rec_type != $rec ]; then
8906                         echo "FAILED test_60a wrong record type $rec_type," \
8907                               "should be $rec"
8908                         pass=false
8909                         break
8910                 fi
8911
8912                 #check obj path if record type is LLOG_LOGID_MAGIC
8913                 if [ "$rec" == "1064553b" ]; then
8914                         path=$(do_facet mgs $llog_reader $obj_file |
8915                                 grep "path=" | awk '{ print $NF }' |
8916                                 sed -e "s/^path=//g")
8917                         if [ $obj_file != $mntpt/$path ]; then
8918                                 echo "FAILED test_60a wrong obj path" \
8919                                       "$montpt/$path, should be $obj_file"
8920                                 pass=false
8921                                 break
8922                         fi
8923                 fi
8924         done
8925         rm -f $TMP/$tfile
8926         #restart mgs before "error", otherwise it will block the next test
8927         stop mgs || error "stop mgs failed"
8928         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8929         $pass || error "test failed, see FAILED test_60a messages for specifics"
8930 }
8931 run_test 60a "llog_test run from kernel module and test llog_reader"
8932
8933 test_60b() { # bug 6411
8934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8935
8936         dmesg > $DIR/$tfile
8937         LLOG_COUNT=$(do_facet mgs dmesg |
8938                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8939                           /llog_[a-z]*.c:[0-9]/ {
8940                                 if (marker)
8941                                         from_marker++
8942                                 from_begin++
8943                           }
8944                           END {
8945                                 if (marker)
8946                                         print from_marker
8947                                 else
8948                                         print from_begin
8949                           }")
8950
8951         [[ $LLOG_COUNT -gt 120 ]] &&
8952                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8953 }
8954 run_test 60b "limit repeated messages from CERROR/CWARN"
8955
8956 test_60c() {
8957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8958
8959         echo "create 5000 files"
8960         createmany -o $DIR/f60c- 5000
8961 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8962         lctl set_param fail_loc=0x80000137
8963         unlinkmany $DIR/f60c- 5000
8964         lctl set_param fail_loc=0
8965 }
8966 run_test 60c "unlink file when mds full"
8967
8968 test_60d() {
8969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8970
8971         SAVEPRINTK=$(lctl get_param -n printk)
8972         # verify "lctl mark" is even working"
8973         MESSAGE="test message ID $RANDOM $$"
8974         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8975         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8976
8977         lctl set_param printk=0 || error "set lnet.printk failed"
8978         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8979         MESSAGE="new test message ID $RANDOM $$"
8980         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8981         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8982         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8983
8984         lctl set_param -n printk="$SAVEPRINTK"
8985 }
8986 run_test 60d "test printk console message masking"
8987
8988 test_60e() {
8989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8990         remote_mds_nodsh && skip "remote MDS with nodsh"
8991
8992         touch $DIR/$tfile
8993 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8994         do_facet mds1 lctl set_param fail_loc=0x15b
8995         rm $DIR/$tfile
8996 }
8997 run_test 60e "no space while new llog is being created"
8998
8999 test_60f() {
9000         local old_path=$($LCTL get_param -n debug_path)
9001
9002         stack_trap "$LCTL set_param debug_path=$old_path"
9003         stack_trap "rm -f $TMP/$tfile*"
9004         rm -f $TMP/$tfile* 2> /dev/null
9005         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9006         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9007         test_mkdir $DIR/$tdir
9008         # retry in case the open is cached and not released
9009         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9010                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9011                 sleep 0.1
9012         done
9013         ls $TMP/$tfile*
9014         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9015 }
9016 run_test 60f "change debug_path works"
9017
9018 test_60g() {
9019         local pid
9020         local i
9021
9022         test_mkdir -c $MDSCOUNT $DIR/$tdir
9023
9024         (
9025                 local index=0
9026                 while true; do
9027                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9028                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9029                                 2>/dev/null
9030                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9031                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9032                         index=$((index + 1))
9033                 done
9034         ) &
9035
9036         pid=$!
9037
9038         for i in {0..100}; do
9039                 # define OBD_FAIL_OSD_TXN_START    0x19a
9040                 local index=$((i % MDSCOUNT + 1))
9041
9042                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9043                         > /dev/null
9044                 sleep 0.01
9045         done
9046
9047         kill -9 $pid
9048
9049         for i in $(seq $MDSCOUNT); do
9050                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9051         done
9052
9053         mkdir $DIR/$tdir/new || error "mkdir failed"
9054         rmdir $DIR/$tdir/new || error "rmdir failed"
9055
9056         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9057                 -t namespace
9058         for i in $(seq $MDSCOUNT); do
9059                 wait_update_facet mds$i "$LCTL get_param -n \
9060                         mdd.$(facet_svc mds$i).lfsck_namespace |
9061                         awk '/^status/ { print \\\$2 }'" "completed"
9062         done
9063
9064         ls -R $DIR/$tdir
9065         rm -rf $DIR/$tdir || error "rmdir failed"
9066 }
9067 run_test 60g "transaction abort won't cause MDT hung"
9068
9069 test_60h() {
9070         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9071                 skip "Need MDS version at least 2.12.52"
9072         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9073
9074         local f
9075
9076         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9077         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9078         for fail_loc in 0x80000188 0x80000189; do
9079                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9080                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9081                         error "mkdir $dir-$fail_loc failed"
9082                 for i in {0..10}; do
9083                         # create may fail on missing stripe
9084                         echo $i > $DIR/$tdir-$fail_loc/$i
9085                 done
9086                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9087                         error "getdirstripe $tdir-$fail_loc failed"
9088                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9089                         error "migrate $tdir-$fail_loc failed"
9090                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9091                         error "getdirstripe $tdir-$fail_loc failed"
9092                 pushd $DIR/$tdir-$fail_loc
9093                 for f in *; do
9094                         echo $f | cmp $f - || error "$f data mismatch"
9095                 done
9096                 popd
9097                 rm -rf $DIR/$tdir-$fail_loc
9098         done
9099 }
9100 run_test 60h "striped directory with missing stripes can be accessed"
9101
9102 function t60i_load() {
9103         mkdir $DIR/$tdir
9104         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9105         $LCTL set_param fail_loc=0x131c fail_val=1
9106         for ((i=0; i<5000; i++)); do
9107                 touch $DIR/$tdir/f$i
9108         done
9109 }
9110
9111 test_60i() {
9112         changelog_register || error "changelog_register failed"
9113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9114         changelog_users $SINGLEMDS | grep -q $cl_user ||
9115                 error "User $cl_user not found in changelog_users"
9116         changelog_chmask "ALL"
9117         t60i_load &
9118         local PID=$!
9119         for((i=0; i<100; i++)); do
9120                 changelog_dump >/dev/null ||
9121                         error "can't read changelog"
9122         done
9123         kill $PID
9124         wait $PID
9125         changelog_deregister || error "changelog_deregister failed"
9126         $LCTL set_param fail_loc=0
9127 }
9128 run_test 60i "llog: new record vs reader race"
9129
9130 test_60j() {
9131         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9132                 skip "need MDS version at least 2.15.50"
9133         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9134         remote_mds_nodsh && skip "remote MDS with nodsh"
9135         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9136
9137         changelog_users $SINGLEMDS | grep "^cl" &&
9138                 skip "active changelog user"
9139
9140         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9141
9142         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9143                 skip_env "missing llog_reader"
9144
9145         mkdir_on_mdt0 $DIR/$tdir
9146
9147         local f=$DIR/$tdir/$tfile
9148         local mdt_dev
9149         local tmpfile
9150         local plain
9151
9152         changelog_register || error "cannot register changelog user"
9153
9154         # set changelog_mask to ALL
9155         changelog_chmask "ALL"
9156         changelog_clear
9157
9158         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9159         unlinkmany ${f}- 100 || error "unlinkmany failed"
9160
9161         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9162         mdt_dev=$(facet_device $SINGLEMDS)
9163
9164         do_facet $SINGLEMDS sync
9165         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9166                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9167                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9168
9169         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9170
9171         # if $tmpfile is not on EXT3 filesystem for some reason
9172         [[ ${plain:0:1} == 'O' ]] ||
9173                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9174
9175         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9176                 $mdt_dev; stat -c %s $tmpfile")
9177         echo "Truncate llog from $size to $((size - size % 8192))"
9178         size=$((size - size % 8192))
9179         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9180         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9181                 grep -c 'in bitmap only')
9182         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9183
9184         size=$((size - 9000))
9185         echo "Corrupt llog in the middle at $size"
9186         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9187                 count=333 conv=notrunc
9188         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9189                 grep -c 'next chunk')
9190         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9191 }
9192 run_test 60j "llog_reader reports corruptions"
9193
9194 test_61a() {
9195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9196
9197         f="$DIR/f61"
9198         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9199         cancel_lru_locks osc
9200         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9201         sync
9202 }
9203 run_test 61a "mmap() writes don't make sync hang ================"
9204
9205 test_61b() {
9206         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9207 }
9208 run_test 61b "mmap() of unstriped file is successful"
9209
9210 # bug 2330 - insufficient obd_match error checking causes LBUG
9211 test_62() {
9212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9213
9214         f="$DIR/f62"
9215         echo foo > $f
9216         cancel_lru_locks osc
9217         lctl set_param fail_loc=0x405
9218         cat $f && error "cat succeeded, expect -EIO"
9219         lctl set_param fail_loc=0
9220 }
9221 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9222 # match every page all of the time.
9223 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9224
9225 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9226 # Though this test is irrelevant anymore, it helped to reveal some
9227 # other grant bugs (LU-4482), let's keep it.
9228 test_63a() {   # was test_63
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230
9231         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9232
9233         for i in `seq 10` ; do
9234                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9235                 sleep 5
9236                 kill $!
9237                 sleep 1
9238         done
9239
9240         rm -f $DIR/f63 || true
9241 }
9242 run_test 63a "Verify oig_wait interruption does not crash ======="
9243
9244 # bug 2248 - async write errors didn't return to application on sync
9245 # bug 3677 - async write errors left page locked
9246 test_63b() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248
9249         debugsave
9250         lctl set_param debug=-1
9251
9252         # ensure we have a grant to do async writes
9253         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9254         rm $DIR/$tfile
9255
9256         sync    # sync lest earlier test intercept the fail_loc
9257
9258         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9259         lctl set_param fail_loc=0x80000406
9260         $MULTIOP $DIR/$tfile Owy && \
9261                 error "sync didn't return ENOMEM"
9262         sync; sleep 2; sync     # do a real sync this time to flush page
9263         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9264                 error "locked page left in cache after async error" || true
9265         debugrestore
9266 }
9267 run_test 63b "async write errors should be returned to fsync ==="
9268
9269 test_64a () {
9270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9271
9272         lfs df $DIR
9273         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9274 }
9275 run_test 64a "verify filter grant calculations (in kernel) ====="
9276
9277 test_64b () {
9278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9279
9280         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9281 }
9282 run_test 64b "check out-of-space detection on client"
9283
9284 test_64c() {
9285         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9286 }
9287 run_test 64c "verify grant shrink"
9288
9289 import_param() {
9290         local tgt=$1
9291         local param=$2
9292
9293         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9294 }
9295
9296 # this does exactly what osc_request.c:osc_announce_cached() does in
9297 # order to calculate max amount of grants to ask from server
9298 want_grant() {
9299         local tgt=$1
9300
9301         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9302         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9303
9304         ((rpc_in_flight++));
9305         nrpages=$((nrpages * rpc_in_flight))
9306
9307         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9308
9309         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9310
9311         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9312         local undirty=$((nrpages * PAGE_SIZE))
9313
9314         local max_extent_pages
9315         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9316         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9317         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9318         local grant_extent_tax
9319         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9320
9321         undirty=$((undirty + nrextents * grant_extent_tax))
9322
9323         echo $undirty
9324 }
9325
9326 # this is size of unit for grant allocation. It should be equal to
9327 # what tgt_grant.c:tgt_grant_chunk() calculates
9328 grant_chunk() {
9329         local tgt=$1
9330         local max_brw_size
9331         local grant_extent_tax
9332
9333         max_brw_size=$(import_param $tgt max_brw_size)
9334
9335         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9336
9337         echo $(((max_brw_size + grant_extent_tax) * 2))
9338 }
9339
9340 test_64d() {
9341         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9342                 skip "OST < 2.10.55 doesn't limit grants enough"
9343
9344         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9345
9346         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9347                 skip "no grant_param connect flag"
9348
9349         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9350
9351         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9352         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9353
9354
9355         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9356         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9357
9358         $LFS setstripe $DIR/$tfile -i 0 -c 1
9359         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9360         ddpid=$!
9361
9362         while kill -0 $ddpid; do
9363                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9364
9365                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9366                         kill $ddpid
9367                         error "cur_grant $cur_grant > $max_cur_granted"
9368                 fi
9369
9370                 sleep 1
9371         done
9372 }
9373 run_test 64d "check grant limit exceed"
9374
9375 check_grants() {
9376         local tgt=$1
9377         local expected=$2
9378         local msg=$3
9379         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9380
9381         ((cur_grants == expected)) ||
9382                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9383 }
9384
9385 round_up_p2() {
9386         echo $((($1 + $2 - 1) & ~($2 - 1)))
9387 }
9388
9389 test_64e() {
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9392                 skip "Need OSS version at least 2.11.56"
9393
9394         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9395         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9396         $LCTL set_param debug=+cache
9397
9398         # Remount client to reset grant
9399         remount_client $MOUNT || error "failed to remount client"
9400         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9401
9402         local init_grants=$(import_param $osc_tgt initial_grant)
9403
9404         check_grants $osc_tgt $init_grants "init grants"
9405
9406         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9407         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9408         local gbs=$(import_param $osc_tgt grant_block_size)
9409
9410         # write random number of bytes from max_brw_size / 4 to max_brw_size
9411         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9412         # align for direct io
9413         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9414         # round to grant consumption unit
9415         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9416
9417         local grants=$((wb_round_up + extent_tax))
9418
9419         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9420
9421         # define OBD_FAIL_TGT_NO_GRANT 0x725
9422         # make the server not grant more back
9423         do_facet ost1 $LCTL set_param fail_loc=0x725
9424         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9425
9426         do_facet ost1 $LCTL set_param fail_loc=0
9427
9428         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9429
9430         rm -f $DIR/$tfile || error "rm failed"
9431
9432         # Remount client to reset grant
9433         remount_client $MOUNT || error "failed to remount client"
9434         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9435
9436         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9437
9438         # define OBD_FAIL_TGT_NO_GRANT 0x725
9439         # make the server not grant more back
9440         do_facet ost1 $LCTL set_param fail_loc=0x725
9441         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9442         do_facet ost1 $LCTL set_param fail_loc=0
9443
9444         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9445 }
9446 run_test 64e "check grant consumption (no grant allocation)"
9447
9448 test_64f() {
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450
9451         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9452         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9453         $LCTL set_param debug=+cache
9454
9455         # Remount client to reset grant
9456         remount_client $MOUNT || error "failed to remount client"
9457         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9458
9459         local init_grants=$(import_param $osc_tgt initial_grant)
9460         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9461         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9462         local gbs=$(import_param $osc_tgt grant_block_size)
9463         local chunk=$(grant_chunk $osc_tgt)
9464
9465         # write random number of bytes from max_brw_size / 4 to max_brw_size
9466         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9467         # align for direct io
9468         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9469         # round to grant consumption unit
9470         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9471
9472         local grants=$((wb_round_up + extent_tax))
9473
9474         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9475         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9476                 error "error writing to $DIR/$tfile"
9477
9478         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9479                 "direct io with grant allocation"
9480
9481         rm -f $DIR/$tfile || error "rm failed"
9482
9483         # Remount client to reset grant
9484         remount_client $MOUNT || error "failed to remount client"
9485         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9486
9487         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9488
9489         local cmd="oO_WRONLY:w${write_bytes}_yc"
9490
9491         $MULTIOP $DIR/$tfile $cmd &
9492         MULTIPID=$!
9493         sleep 1
9494
9495         check_grants $osc_tgt $((init_grants - grants)) \
9496                 "buffered io, not write rpc"
9497
9498         kill -USR1 $MULTIPID
9499         wait
9500
9501         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9502                 "buffered io, one RPC"
9503 }
9504 run_test 64f "check grant consumption (with grant allocation)"
9505
9506 test_64g() {
9507         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9508                 skip "Need MDS version at least 2.14.56"
9509
9510         local mdts=$(comma_list $(mdts_nodes))
9511
9512         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9513                         tr '\n' ' ')
9514         stack_trap "$LCTL set_param $old"
9515
9516         # generate dirty pages and increase dirty granted on MDT
9517         stack_trap "rm -f $DIR/$tfile-*"
9518         for (( i = 0; i < 10; i++)); do
9519                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9520                         error "can't set stripe"
9521                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9522                         error "can't dd"
9523                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9524                         $LFS getstripe $DIR/$tfile-$i
9525                         error "not DoM file"
9526                 }
9527         done
9528
9529         # flush dirty pages
9530         sync
9531
9532         # wait until grant shrink reset grant dirty on MDTs
9533         for ((i = 0; i < 120; i++)); do
9534                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9535                         awk '{sum=sum+$1} END {print sum}')
9536                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9537                 echo "$grant_dirty grants, $vm_dirty pages"
9538                 (( grant_dirty + vm_dirty == 0 )) && break
9539                 (( i == 3 )) && sync &&
9540                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9541                 sleep 1
9542         done
9543
9544         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9545                 awk '{sum=sum+$1} END {print sum}')
9546         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9547 }
9548 run_test 64g "grant shrink on MDT"
9549
9550 test_64h() {
9551         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9552                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9553
9554         local instance=$($LFS getname -i $DIR)
9555         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9556         local num_exps=$(do_facet ost1 \
9557             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9558         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9559         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9561
9562         # 10MiB is for file to be written, max_brw_size * 16 *
9563         # num_exps is space reserve so that tgt_grant_shrink() decided
9564         # to not shrink
9565         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9566         (( avail * 1024 < expect )) &&
9567                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9568
9569         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9570         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9571         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9572         $LCTL set_param osc.*OST0000*.grant_shrink=1
9573         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9574
9575         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9576         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9577
9578         # drop cache so that coming read would do rpc
9579         cancel_lru_locks osc
9580
9581         # shrink interval is set to 10, pause for 7 seconds so that
9582         # grant thread did not wake up yet but coming read entered
9583         # shrink mode for rpc (osc_should_shrink_grant())
9584         sleep 7
9585
9586         declare -a cur_grant_bytes
9587         declare -a tot_granted
9588         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9589         tot_granted[0]=$(do_facet ost1 \
9590             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9591
9592         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9593
9594         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9595         tot_granted[1]=$(do_facet ost1 \
9596             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9597
9598         # grant change should be equal on both sides
9599         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9600                 tot_granted[0] - tot_granted[1])) ||
9601                 error "grant change mismatch, "                                \
9602                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9603                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9604 }
9605 run_test 64h "grant shrink on read"
9606
9607 test_64i() {
9608         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9609                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9610
9611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9612         remote_ost_nodsh && skip "remote OSTs with nodsh"
9613
9614         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9615
9616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9617
9618         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9619         local instance=$($LFS getname -i $DIR)
9620
9621         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9622         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9623
9624         # shrink grants and simulate rpc loss
9625         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9626         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9627         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9628
9629         fail ost1
9630
9631         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9632
9633         local testid=$(echo $TESTNAME | tr '_' ' ')
9634
9635         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9636                 grep "GRANT, real grant" &&
9637                 error "client has more grants then it owns" || true
9638 }
9639 run_test 64i "shrink on reconnect"
9640
9641 # bug 1414 - set/get directories' stripe info
9642 test_65a() {
9643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9644
9645         test_mkdir $DIR/$tdir
9646         touch $DIR/$tdir/f1
9647         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9648 }
9649 run_test 65a "directory with no stripe info"
9650
9651 test_65b() {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         test_mkdir $DIR/$tdir
9655         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9656
9657         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9658                                                 error "setstripe"
9659         touch $DIR/$tdir/f2
9660         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9661 }
9662 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9663
9664 test_65c() {
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9667
9668         test_mkdir $DIR/$tdir
9669         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9670
9671         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9672                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9673         touch $DIR/$tdir/f3
9674         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9675 }
9676 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9677
9678 test_65d() {
9679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9680
9681         test_mkdir $DIR/$tdir
9682         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9683         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9684
9685         if [[ $STRIPECOUNT -le 0 ]]; then
9686                 sc=1
9687         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9688                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9689                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9690         else
9691                 sc=$(($STRIPECOUNT - 1))
9692         fi
9693         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9694         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9695         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9696                 error "lverify failed"
9697 }
9698 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9699
9700 test_65e() {
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702
9703         test_mkdir $DIR/$tdir
9704
9705         $LFS setstripe $DIR/$tdir || error "setstripe"
9706         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9707                                         error "no stripe info failed"
9708         touch $DIR/$tdir/f6
9709         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9710 }
9711 run_test 65e "directory setstripe defaults"
9712
9713 test_65f() {
9714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9715
9716         test_mkdir $DIR/${tdir}f
9717         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9718                 error "setstripe succeeded" || true
9719 }
9720 run_test 65f "dir setstripe permission (should return error) ==="
9721
9722 test_65g() {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724
9725         test_mkdir $DIR/$tdir
9726         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9727
9728         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9729                 error "setstripe -S failed"
9730         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9731         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9732                 error "delete default stripe failed"
9733 }
9734 run_test 65g "directory setstripe -d"
9735
9736 test_65h() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738
9739         test_mkdir $DIR/$tdir
9740         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9741
9742         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9743                 error "setstripe -S failed"
9744         test_mkdir $DIR/$tdir/dd1
9745         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9746                 error "stripe info inherit failed"
9747 }
9748 run_test 65h "directory stripe info inherit ===================="
9749
9750 test_65i() {
9751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9752
9753         save_layout_restore_at_exit $MOUNT
9754
9755         # bug6367: set non-default striping on root directory
9756         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9757
9758         # bug12836: getstripe on -1 default directory striping
9759         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9760
9761         # bug12836: getstripe -v on -1 default directory striping
9762         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9763
9764         # bug12836: new find on -1 default directory striping
9765         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9766 }
9767 run_test 65i "various tests to set root directory striping"
9768
9769 test_65j() { # bug6367
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771
9772         sync; sleep 1
9773
9774         # if we aren't already remounting for each test, do so for this test
9775         if [ "$I_MOUNTED" = "yes" ]; then
9776                 cleanup || error "failed to unmount"
9777                 setup
9778         fi
9779
9780         save_layout_restore_at_exit $MOUNT
9781
9782         $LFS setstripe -d $MOUNT || error "setstripe failed"
9783 }
9784 run_test 65j "set default striping on root directory (bug 6367)="
9785
9786 cleanup_65k() {
9787         rm -rf $DIR/$tdir
9788         wait_delete_completed
9789         do_facet $SINGLEMDS "lctl set_param -n \
9790                 osp.$ost*MDT0000.max_create_count=$max_count"
9791         do_facet $SINGLEMDS "lctl set_param -n \
9792                 osp.$ost*MDT0000.create_count=$count"
9793         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9794         echo $INACTIVE_OSC "is Activate"
9795
9796         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9797 }
9798
9799 test_65k() { # bug11679
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9802         remote_mds_nodsh && skip "remote MDS with nodsh"
9803
9804         local disable_precreate=true
9805         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9806                 disable_precreate=false
9807
9808         echo "Check OST status: "
9809         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9810                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9811
9812         for OSC in $MDS_OSCS; do
9813                 echo $OSC "is active"
9814                 do_facet $SINGLEMDS lctl --device %$OSC activate
9815         done
9816
9817         for INACTIVE_OSC in $MDS_OSCS; do
9818                 local ost=$(osc_to_ost $INACTIVE_OSC)
9819                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9820                                lov.*md*.target_obd |
9821                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9822
9823                 mkdir -p $DIR/$tdir
9824                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9825                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9826
9827                 echo "Deactivate: " $INACTIVE_OSC
9828                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9829
9830                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9831                               osp.$ost*MDT0000.create_count")
9832                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9833                                   osp.$ost*MDT0000.max_create_count")
9834                 $disable_precreate &&
9835                         do_facet $SINGLEMDS "lctl set_param -n \
9836                                 osp.$ost*MDT0000.max_create_count=0"
9837
9838                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9839                         [ -f $DIR/$tdir/$idx ] && continue
9840                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9841                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9842                                 { cleanup_65k;
9843                                   error "setstripe $idx should succeed"; }
9844                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9845                 done
9846                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9847                 rmdir $DIR/$tdir
9848
9849                 do_facet $SINGLEMDS "lctl set_param -n \
9850                         osp.$ost*MDT0000.max_create_count=$max_count"
9851                 do_facet $SINGLEMDS "lctl set_param -n \
9852                         osp.$ost*MDT0000.create_count=$count"
9853                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9854                 echo $INACTIVE_OSC "is Activate"
9855
9856                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9857         done
9858 }
9859 run_test 65k "validate manual striping works properly with deactivated OSCs"
9860
9861 test_65l() { # bug 12836
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         test_mkdir -p $DIR/$tdir/test_dir
9865         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9866         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9867 }
9868 run_test 65l "lfs find on -1 stripe dir ========================"
9869
9870 test_65m() {
9871         local layout=$(save_layout $MOUNT)
9872         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9873                 restore_layout $MOUNT $layout
9874                 error "setstripe should fail by non-root users"
9875         }
9876         true
9877 }
9878 run_test 65m "normal user can't set filesystem default stripe"
9879
9880 test_65n() {
9881         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9882         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9883                 skip "Need MDS version at least 2.12.50"
9884         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9885
9886         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9887         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9888         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9889
9890         save_layout_restore_at_exit $MOUNT
9891
9892         # new subdirectory under root directory should not inherit
9893         # the default layout from root
9894         local dir1=$MOUNT/$tdir-1
9895         mkdir $dir1 || error "mkdir $dir1 failed"
9896         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9897                 error "$dir1 shouldn't have LOV EA"
9898
9899         # delete the default layout on root directory
9900         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9901
9902         local dir2=$MOUNT/$tdir-2
9903         mkdir $dir2 || error "mkdir $dir2 failed"
9904         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9905                 error "$dir2 shouldn't have LOV EA"
9906
9907         # set a new striping pattern on root directory
9908         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9909         local new_def_stripe_size=$((def_stripe_size * 2))
9910         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9911                 error "set stripe size on $MOUNT failed"
9912
9913         # new file created in $dir2 should inherit the new stripe size from
9914         # the filesystem default
9915         local file2=$dir2/$tfile-2
9916         touch $file2 || error "touch $file2 failed"
9917
9918         local file2_stripe_size=$($LFS getstripe -S $file2)
9919         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9920         {
9921                 echo "file2_stripe_size: '$file2_stripe_size'"
9922                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9923                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9924         }
9925
9926         local dir3=$MOUNT/$tdir-3
9927         mkdir $dir3 || error "mkdir $dir3 failed"
9928         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9929         # the root layout, which is the actual default layout that will be used
9930         # when new files are created in $dir3.
9931         local dir3_layout=$(get_layout_param $dir3)
9932         local root_dir_layout=$(get_layout_param $MOUNT)
9933         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9934         {
9935                 echo "dir3_layout: '$dir3_layout'"
9936                 echo "root_dir_layout: '$root_dir_layout'"
9937                 error "$dir3 should show the default layout from $MOUNT"
9938         }
9939
9940         # set OST pool on root directory
9941         local pool=$TESTNAME
9942         pool_add $pool || error "add $pool failed"
9943         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9944                 error "add targets to $pool failed"
9945
9946         $LFS setstripe -p $pool $MOUNT ||
9947                 error "set OST pool on $MOUNT failed"
9948
9949         # new file created in $dir3 should inherit the pool from
9950         # the filesystem default
9951         local file3=$dir3/$tfile-3
9952         touch $file3 || error "touch $file3 failed"
9953
9954         local file3_pool=$($LFS getstripe -p $file3)
9955         [[ "$file3_pool" = "$pool" ]] ||
9956                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9957
9958         local dir4=$MOUNT/$tdir-4
9959         mkdir $dir4 || error "mkdir $dir4 failed"
9960         local dir4_layout=$(get_layout_param $dir4)
9961         root_dir_layout=$(get_layout_param $MOUNT)
9962         echo "$LFS getstripe -d $dir4"
9963         $LFS getstripe -d $dir4
9964         echo "$LFS getstripe -d $MOUNT"
9965         $LFS getstripe -d $MOUNT
9966         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9967         {
9968                 echo "dir4_layout: '$dir4_layout'"
9969                 echo "root_dir_layout: '$root_dir_layout'"
9970                 error "$dir4 should show the default layout from $MOUNT"
9971         }
9972
9973         # new file created in $dir4 should inherit the pool from
9974         # the filesystem default
9975         local file4=$dir4/$tfile-4
9976         touch $file4 || error "touch $file4 failed"
9977
9978         local file4_pool=$($LFS getstripe -p $file4)
9979         [[ "$file4_pool" = "$pool" ]] ||
9980                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9981
9982         # new subdirectory under non-root directory should inherit
9983         # the default layout from its parent directory
9984         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9985                 error "set directory layout on $dir4 failed"
9986
9987         local dir5=$dir4/$tdir-5
9988         mkdir $dir5 || error "mkdir $dir5 failed"
9989
9990         dir4_layout=$(get_layout_param $dir4)
9991         local dir5_layout=$(get_layout_param $dir5)
9992         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9993         {
9994                 echo "dir4_layout: '$dir4_layout'"
9995                 echo "dir5_layout: '$dir5_layout'"
9996                 error "$dir5 should inherit the default layout from $dir4"
9997         }
9998
9999         # though subdir under ROOT doesn't inherit default layout, but
10000         # its sub dir/file should be created with default layout.
10001         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10002         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10003                 skip "Need MDS version at least 2.12.59"
10004
10005         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10006         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10007         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10008
10009         if [ $default_lmv_hash == "none" ]; then
10010                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10011         else
10012                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10013                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10014         fi
10015
10016         $LFS setdirstripe -D -c 2 $MOUNT ||
10017                 error "setdirstripe -D -c 2 failed"
10018         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10019         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10020         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10021
10022         # $dir4 layout includes pool
10023         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10024         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10025                 error "pool lost on setstripe"
10026         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10027         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10028                 error "pool lost on compound layout setstripe"
10029 }
10030 run_test 65n "don't inherit default layout from root for new subdirectories"
10031
10032 test_65o() {
10033         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10034                 skip "need MDS version at least 2.14.57"
10035
10036         # set OST pool on root directory
10037         local pool=$TESTNAME
10038
10039         pool_add $pool || error "add $pool failed"
10040         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10041                 error "add targets to $pool failed"
10042
10043         local dir1=$MOUNT/$tdir
10044
10045         mkdir $dir1 || error "mkdir $dir1 failed"
10046
10047         # set a new striping pattern on root directory
10048         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10049
10050         $LFS setstripe -p $pool $dir1 ||
10051                 error "set directory layout on $dir1 failed"
10052
10053         # $dir1 layout includes pool
10054         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10055         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10056                 error "pool lost on setstripe"
10057         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10058         $LFS getstripe $dir1
10059         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10060                 error "pool lost on compound layout setstripe"
10061
10062         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10063                 error "setdirstripe failed on sub-dir with inherited pool"
10064         $LFS getstripe $dir1/dir2
10065         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10066                 error "pool lost on compound layout setdirstripe"
10067
10068         $LFS setstripe -E -1 -c 1 $dir1
10069         $LFS getstripe -d $dir1
10070         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10071                 error "pool lost on setstripe"
10072 }
10073 run_test 65o "pool inheritance for mdt component"
10074
10075 test_65p () { # LU-16152
10076         local src_dir=$DIR/$tdir/src_dir
10077         local dst_dir=$DIR/$tdir/dst_dir
10078         local yaml_file=$DIR/$tdir/layout.yaml
10079         local border
10080
10081         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10082                 skip "Need at least version 2.15.51"
10083
10084         test_mkdir -p $src_dir
10085         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10086                 error "failed to setstripe"
10087         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10088                 error "failed to getstripe"
10089
10090         test_mkdir -p $dst_dir
10091         $LFS setstripe --yaml $yaml_file $dst_dir ||
10092                 error "failed to setstripe with yaml file"
10093         border=$($LFS getstripe -d $dst_dir |
10094                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10095                 error "failed to getstripe"
10096
10097         # 2048M is 0x80000000, or 2147483648
10098         (( $border == 2147483648 )) ||
10099                 error "failed to handle huge number in yaml layout"
10100 }
10101 run_test 65p "setstripe with yaml file and huge number"
10102
10103 # bug 2543 - update blocks count on client
10104 test_66() {
10105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10106
10107         local COUNT=${COUNT:-8}
10108         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10109         sync; sync_all_data; sync; sync_all_data
10110         cancel_lru_locks osc
10111         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10112         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10113 }
10114 run_test 66 "update inode blocks count on client ==============="
10115
10116 meminfo() {
10117         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10118 }
10119
10120 swap_used() {
10121         swapon -s | awk '($1 == "'$1'") { print $4 }'
10122 }
10123
10124 # bug5265, obdfilter oa2dentry return -ENOENT
10125 # #define OBD_FAIL_SRV_ENOENT 0x217
10126 test_69() {
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128         remote_ost_nodsh && skip "remote OST with nodsh"
10129
10130         f="$DIR/$tfile"
10131         $LFS setstripe -c 1 -i 0 $f
10132
10133         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10134
10135         do_facet ost1 lctl set_param fail_loc=0x217
10136         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10137         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10138
10139         do_facet ost1 lctl set_param fail_loc=0
10140         $DIRECTIO write $f 0 2 || error "write error"
10141
10142         cancel_lru_locks osc
10143         $DIRECTIO read $f 0 1 || error "read error"
10144
10145         do_facet ost1 lctl set_param fail_loc=0x217
10146         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10147
10148         do_facet ost1 lctl set_param fail_loc=0
10149         rm -f $f
10150 }
10151 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10152
10153 test_71() {
10154         test_mkdir $DIR/$tdir
10155         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10156         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10157 }
10158 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10159
10160 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10162         [ "$RUNAS_ID" = "$UID" ] &&
10163                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10164         # Check that testing environment is properly set up. Skip if not
10165         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10166                 skip_env "User $RUNAS_ID does not exist - skipping"
10167
10168         touch $DIR/$tfile
10169         chmod 777 $DIR/$tfile
10170         chmod ug+s $DIR/$tfile
10171         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10172                 error "$RUNAS dd $DIR/$tfile failed"
10173         # See if we are still setuid/sgid
10174         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10175                 error "S/gid is not dropped on write"
10176         # Now test that MDS is updated too
10177         cancel_lru_locks mdc
10178         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10179                 error "S/gid is not dropped on MDS"
10180         rm -f $DIR/$tfile
10181 }
10182 run_test 72a "Test that remove suid works properly (bug5695) ===="
10183
10184 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10185         local perm
10186
10187         [ "$RUNAS_ID" = "$UID" ] &&
10188                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10189         [ "$RUNAS_ID" -eq 0 ] &&
10190                 skip_env "RUNAS_ID = 0 -- skipping"
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         # Check that testing environment is properly set up. Skip if not
10193         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10194                 skip_env "User $RUNAS_ID does not exist - skipping"
10195
10196         touch $DIR/${tfile}-f{g,u}
10197         test_mkdir $DIR/${tfile}-dg
10198         test_mkdir $DIR/${tfile}-du
10199         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10200         chmod g+s $DIR/${tfile}-{f,d}g
10201         chmod u+s $DIR/${tfile}-{f,d}u
10202         for perm in 777 2777 4777; do
10203                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10204                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10205                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10206                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10207         done
10208         true
10209 }
10210 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10211
10212 # bug 3462 - multiple simultaneous MDC requests
10213 test_73() {
10214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10215
10216         test_mkdir $DIR/d73-1
10217         test_mkdir $DIR/d73-2
10218         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10219         pid1=$!
10220
10221         lctl set_param fail_loc=0x80000129
10222         $MULTIOP $DIR/d73-1/f73-2 Oc &
10223         sleep 1
10224         lctl set_param fail_loc=0
10225
10226         $MULTIOP $DIR/d73-2/f73-3 Oc &
10227         pid3=$!
10228
10229         kill -USR1 $pid1
10230         wait $pid1 || return 1
10231
10232         sleep 25
10233
10234         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10235         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10236         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10237
10238         rm -rf $DIR/d73-*
10239 }
10240 run_test 73 "multiple MDC requests (should not deadlock)"
10241
10242 test_74a() { # bug 6149, 6184
10243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10244
10245         touch $DIR/f74a
10246         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10247         #
10248         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10249         # will spin in a tight reconnection loop
10250         $LCTL set_param fail_loc=0x8000030e
10251         # get any lock that won't be difficult - lookup works.
10252         ls $DIR/f74a
10253         $LCTL set_param fail_loc=0
10254         rm -f $DIR/f74a
10255         true
10256 }
10257 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10258
10259 test_74b() { # bug 13310
10260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10261
10262         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10263         #
10264         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10265         # will spin in a tight reconnection loop
10266         $LCTL set_param fail_loc=0x8000030e
10267         # get a "difficult" lock
10268         touch $DIR/f74b
10269         $LCTL set_param fail_loc=0
10270         rm -f $DIR/f74b
10271         true
10272 }
10273 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10274
10275 test_74c() {
10276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10277
10278         #define OBD_FAIL_LDLM_NEW_LOCK
10279         $LCTL set_param fail_loc=0x319
10280         touch $DIR/$tfile && error "touch successful"
10281         $LCTL set_param fail_loc=0
10282         true
10283 }
10284 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10285
10286 slab_lic=/sys/kernel/slab/lustre_inode_cache
10287 num_objects() {
10288         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10289         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10290                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10291 }
10292
10293 test_76a() { # Now for b=20433, added originally in b=1443
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295
10296         cancel_lru_locks osc
10297         # there may be some slab objects cached per core
10298         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10299         local before=$(num_objects)
10300         local count=$((512 * cpus))
10301         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10302         local margin=$((count / 10))
10303         if [[ -f $slab_lic/aliases ]]; then
10304                 local aliases=$(cat $slab_lic/aliases)
10305                 (( aliases > 0 )) && margin=$((margin * aliases))
10306         fi
10307
10308         echo "before slab objects: $before"
10309         for i in $(seq $count); do
10310                 touch $DIR/$tfile
10311                 rm -f $DIR/$tfile
10312         done
10313         cancel_lru_locks osc
10314         local after=$(num_objects)
10315         echo "created: $count, after slab objects: $after"
10316         # shared slab counts are not very accurate, allow significant margin
10317         # the main goal is that the cache growth is not permanently > $count
10318         while (( after > before + margin )); do
10319                 sleep 1
10320                 after=$(num_objects)
10321                 wait=$((wait + 1))
10322                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10323                 if (( wait > 60 )); then
10324                         error "inode slab grew from $before+$margin to $after"
10325                 fi
10326         done
10327 }
10328 run_test 76a "confirm clients recycle inodes properly ===="
10329
10330 test_76b() {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10333
10334         local count=512
10335         local before=$(num_objects)
10336
10337         for i in $(seq $count); do
10338                 mkdir $DIR/$tdir
10339                 rmdir $DIR/$tdir
10340         done
10341
10342         local after=$(num_objects)
10343         local wait=0
10344
10345         while (( after > before )); do
10346                 sleep 1
10347                 after=$(num_objects)
10348                 wait=$((wait + 1))
10349                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10350                 if (( wait > 60 )); then
10351                         error "inode slab grew from $before to $after"
10352                 fi
10353         done
10354
10355         echo "slab objects before: $before, after: $after"
10356 }
10357 run_test 76b "confirm clients recycle directory inodes properly ===="
10358
10359 export ORIG_CSUM=""
10360 set_checksums()
10361 {
10362         # Note: in sptlrpc modes which enable its own bulk checksum, the
10363         # original crc32_le bulk checksum will be automatically disabled,
10364         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10365         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10366         # In this case set_checksums() will not be no-op, because sptlrpc
10367         # bulk checksum will be enabled all through the test.
10368
10369         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10370         lctl set_param -n osc.*.checksums $1
10371         return 0
10372 }
10373
10374 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10375                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10376 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10377                              tr -d [] | head -n1)}
10378 set_checksum_type()
10379 {
10380         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10381         rc=$?
10382         log "set checksum type to $1, rc = $rc"
10383         return $rc
10384 }
10385
10386 get_osc_checksum_type()
10387 {
10388         # arugment 1: OST name, like OST0000
10389         ost=$1
10390         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10391                         sed 's/.*\[\(.*\)\].*/\1/g')
10392         rc=$?
10393         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10394         echo $checksum_type
10395 }
10396
10397 F77_TMP=$TMP/f77-temp
10398 F77SZ=8
10399 setup_f77() {
10400         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10401                 error "error writing to $F77_TMP"
10402 }
10403
10404 test_77a() { # bug 10889
10405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10406         $GSS && skip_env "could not run with gss"
10407
10408         [ ! -f $F77_TMP ] && setup_f77
10409         set_checksums 1
10410         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10411         set_checksums 0
10412         rm -f $DIR/$tfile
10413 }
10414 run_test 77a "normal checksum read/write operation"
10415
10416 test_77b() { # bug 10889
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418         $GSS && skip_env "could not run with gss"
10419
10420         [ ! -f $F77_TMP ] && setup_f77
10421         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10422         $LCTL set_param fail_loc=0x80000409
10423         set_checksums 1
10424
10425         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10426                 error "dd error: $?"
10427         $LCTL set_param fail_loc=0
10428
10429         for algo in $CKSUM_TYPES; do
10430                 cancel_lru_locks osc
10431                 set_checksum_type $algo
10432                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10433                 $LCTL set_param fail_loc=0x80000408
10434                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10435                 $LCTL set_param fail_loc=0
10436         done
10437         set_checksums 0
10438         set_checksum_type $ORIG_CSUM_TYPE
10439         rm -f $DIR/$tfile
10440 }
10441 run_test 77b "checksum error on client write, read"
10442
10443 cleanup_77c() {
10444         trap 0
10445         set_checksums 0
10446         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10447         $check_ost &&
10448                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10449         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10450         $check_ost && [ -n "$ost_file_prefix" ] &&
10451                 do_facet ost1 rm -f ${ost_file_prefix}\*
10452 }
10453
10454 test_77c() {
10455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10456         $GSS && skip_env "could not run with gss"
10457         remote_ost_nodsh && skip "remote OST with nodsh"
10458
10459         local bad1
10460         local osc_file_prefix
10461         local osc_file
10462         local check_ost=false
10463         local ost_file_prefix
10464         local ost_file
10465         local orig_cksum
10466         local dump_cksum
10467         local fid
10468
10469         # ensure corruption will occur on first OSS/OST
10470         $LFS setstripe -i 0 $DIR/$tfile
10471
10472         [ ! -f $F77_TMP ] && setup_f77
10473         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10474                 error "dd write error: $?"
10475         fid=$($LFS path2fid $DIR/$tfile)
10476
10477         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10478         then
10479                 check_ost=true
10480                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10481                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10482         else
10483                 echo "OSS do not support bulk pages dump upon error"
10484         fi
10485
10486         osc_file_prefix=$($LCTL get_param -n debug_path)
10487         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10488
10489         trap cleanup_77c EXIT
10490
10491         set_checksums 1
10492         # enable bulk pages dump upon error on Client
10493         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10494         # enable bulk pages dump upon error on OSS
10495         $check_ost &&
10496                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10497
10498         # flush Client cache to allow next read to reach OSS
10499         cancel_lru_locks osc
10500
10501         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10502         $LCTL set_param fail_loc=0x80000408
10503         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10504         $LCTL set_param fail_loc=0
10505
10506         rm -f $DIR/$tfile
10507
10508         # check cksum dump on Client
10509         osc_file=$(ls ${osc_file_prefix}*)
10510         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10511         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10512         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10513         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10514         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10515                      cksum)
10516         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10517         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10518                 error "dump content does not match on Client"
10519
10520         $check_ost || skip "No need to check cksum dump on OSS"
10521
10522         # check cksum dump on OSS
10523         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10524         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10525         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10526         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10527         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10528                 error "dump content does not match on OSS"
10529
10530         cleanup_77c
10531 }
10532 run_test 77c "checksum error on client read with debug"
10533
10534 test_77d() { # bug 10889
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536         $GSS && skip_env "could not run with gss"
10537
10538         stack_trap "rm -f $DIR/$tfile"
10539         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10540         $LCTL set_param fail_loc=0x80000409
10541         set_checksums 1
10542         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10543                 error "direct write: rc=$?"
10544         $LCTL set_param fail_loc=0
10545         set_checksums 0
10546
10547         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10548         $LCTL set_param fail_loc=0x80000408
10549         set_checksums 1
10550         cancel_lru_locks osc
10551         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10552                 error "direct read: rc=$?"
10553         $LCTL set_param fail_loc=0
10554         set_checksums 0
10555 }
10556 run_test 77d "checksum error on OST direct write, read"
10557
10558 test_77f() { # bug 10889
10559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10560         $GSS && skip_env "could not run with gss"
10561
10562         set_checksums 1
10563         stack_trap "rm -f $DIR/$tfile"
10564         for algo in $CKSUM_TYPES; do
10565                 cancel_lru_locks osc
10566                 set_checksum_type $algo
10567                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10568                 $LCTL set_param fail_loc=0x409
10569                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10570                         error "direct write succeeded"
10571                 $LCTL set_param fail_loc=0
10572         done
10573         set_checksum_type $ORIG_CSUM_TYPE
10574         set_checksums 0
10575 }
10576 run_test 77f "repeat checksum error on write (expect error)"
10577
10578 test_77g() { # bug 10889
10579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10580         $GSS && skip_env "could not run with gss"
10581         remote_ost_nodsh && skip "remote OST with nodsh"
10582
10583         [ ! -f $F77_TMP ] && setup_f77
10584
10585         local file=$DIR/$tfile
10586         stack_trap "rm -f $file" EXIT
10587
10588         $LFS setstripe -c 1 -i 0 $file
10589         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10590         do_facet ost1 lctl set_param fail_loc=0x8000021a
10591         set_checksums 1
10592         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10593                 error "write error: rc=$?"
10594         do_facet ost1 lctl set_param fail_loc=0
10595         set_checksums 0
10596
10597         cancel_lru_locks osc
10598         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10599         do_facet ost1 lctl set_param fail_loc=0x8000021b
10600         set_checksums 1
10601         cmp $F77_TMP $file || error "file compare failed"
10602         do_facet ost1 lctl set_param fail_loc=0
10603         set_checksums 0
10604 }
10605 run_test 77g "checksum error on OST write, read"
10606
10607 test_77k() { # LU-10906
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         $GSS && skip_env "could not run with gss"
10610
10611         local cksum_param="osc.$FSNAME*.checksums"
10612         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10613         local checksum
10614         local i
10615
10616         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10617         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10618         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10619
10620         for i in 0 1; do
10621                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10622                         error "failed to set checksum=$i on MGS"
10623                 wait_update $HOSTNAME "$get_checksum" $i
10624                 #remount
10625                 echo "remount client, checksum should be $i"
10626                 remount_client $MOUNT || error "failed to remount client"
10627                 checksum=$(eval $get_checksum)
10628                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10629         done
10630         # remove persistent param to avoid races with checksum mountopt below
10631         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10632                 error "failed to delete checksum on MGS"
10633
10634         for opt in "checksum" "nochecksum"; do
10635                 #remount with mount option
10636                 echo "remount client with option $opt, checksum should be $i"
10637                 umount_client $MOUNT || error "failed to umount client"
10638                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10639                         error "failed to mount client with option '$opt'"
10640                 checksum=$(eval $get_checksum)
10641                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10642                 i=$((i - 1))
10643         done
10644
10645         remount_client $MOUNT || error "failed to remount client"
10646 }
10647 run_test 77k "enable/disable checksum correctly"
10648
10649 test_77l() {
10650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10651         $GSS && skip_env "could not run with gss"
10652
10653         set_checksums 1
10654         stack_trap "set_checksums $ORIG_CSUM" EXIT
10655         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10656
10657         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10658
10659         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10660         for algo in $CKSUM_TYPES; do
10661                 set_checksum_type $algo || error "fail to set checksum type $algo"
10662                 osc_algo=$(get_osc_checksum_type OST0000)
10663                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10664
10665                 # no locks, no reqs to let the connection idle
10666                 cancel_lru_locks osc
10667                 lru_resize_disable osc
10668                 wait_osc_import_state client ost1 IDLE
10669
10670                 # ensure ost1 is connected
10671                 stat $DIR/$tfile >/dev/null || error "can't stat"
10672                 wait_osc_import_state client ost1 FULL
10673
10674                 osc_algo=$(get_osc_checksum_type OST0000)
10675                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10676         done
10677         return 0
10678 }
10679 run_test 77l "preferred checksum type is remembered after reconnected"
10680
10681 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10682 rm -f $F77_TMP
10683 unset F77_TMP
10684
10685 test_77m() {
10686         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10687                 skip "Need at least version 2.14.52"
10688         local param=checksum_speed
10689
10690         $LCTL get_param $param || error "reading $param failed"
10691
10692         csum_speeds=$($LCTL get_param -n $param)
10693
10694         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10695                 error "known checksum types are missing"
10696 }
10697 run_test 77m "Verify checksum_speed is correctly read"
10698
10699 check_filefrag_77n() {
10700         local nr_ext=0
10701         local starts=()
10702         local ends=()
10703
10704         while read extidx a b start end rest; do
10705                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10706                         nr_ext=$(( $nr_ext + 1 ))
10707                         starts+=( ${start%..} )
10708                         ends+=( ${end%:} )
10709                 fi
10710         done < <( filefrag -sv $1 )
10711
10712         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10713         return 1
10714 }
10715
10716 test_77n() {
10717         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10718
10719         touch $DIR/$tfile
10720         $TRUNCATE $DIR/$tfile 0
10721         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10722         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10723         check_filefrag_77n $DIR/$tfile ||
10724                 skip "$tfile blocks not contiguous around hole"
10725
10726         set_checksums 1
10727         stack_trap "set_checksums $ORIG_CSUM" EXIT
10728         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10729         stack_trap "rm -f $DIR/$tfile"
10730
10731         for algo in $CKSUM_TYPES; do
10732                 if [[ "$algo" =~ ^t10 ]]; then
10733                         set_checksum_type $algo ||
10734                                 error "fail to set checksum type $algo"
10735                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10736                                 error "fail to read $tfile with $algo"
10737                 fi
10738         done
10739         rm -f $DIR/$tfile
10740         return 0
10741 }
10742 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10743
10744 test_77o() {
10745         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10746                 skip "Need MDS version at least 2.14.55"
10747         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10748                 skip "Need OST version at least 2.14.55"
10749         local ofd=obdfilter
10750         local mdt=mdt
10751
10752         # print OST checksum_type
10753         echo "$ofd.$FSNAME-*.checksum_type:"
10754         do_nodes $(comma_list $(osts_nodes)) \
10755                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10756
10757         # print MDT checksum_type
10758         echo "$mdt.$FSNAME-*.checksum_type:"
10759         do_nodes $(comma_list $(mdts_nodes)) \
10760                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10761
10762         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10763                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10764
10765         (( $o_count == $OSTCOUNT )) ||
10766                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10767
10768         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10769                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10770
10771         (( $m_count == $MDSCOUNT )) ||
10772                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10773 }
10774 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10775
10776 cleanup_test_78() {
10777         trap 0
10778         rm -f $DIR/$tfile
10779 }
10780
10781 test_78() { # bug 10901
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         remote_ost || skip_env "local OST"
10784
10785         NSEQ=5
10786         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10787         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10788         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10789         echo "MemTotal: $MEMTOTAL"
10790
10791         # reserve 256MB of memory for the kernel and other running processes,
10792         # and then take 1/2 of the remaining memory for the read/write buffers.
10793         if [ $MEMTOTAL -gt 512 ] ;then
10794                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10795         else
10796                 # for those poor memory-starved high-end clusters...
10797                 MEMTOTAL=$((MEMTOTAL / 2))
10798         fi
10799         echo "Mem to use for directio: $MEMTOTAL"
10800
10801         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10802         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10803         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10804         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10805                 head -n1)
10806         echo "Smallest OST: $SMALLESTOST"
10807         [[ $SMALLESTOST -lt 10240 ]] &&
10808                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10809
10810         trap cleanup_test_78 EXIT
10811
10812         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10813                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10814
10815         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10816         echo "File size: $F78SIZE"
10817         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10818         for i in $(seq 1 $NSEQ); do
10819                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10820                 echo directIO rdwr round $i of $NSEQ
10821                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10822         done
10823
10824         cleanup_test_78
10825 }
10826 run_test 78 "handle large O_DIRECT writes correctly ============"
10827
10828 test_79() { # bug 12743
10829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10830
10831         wait_delete_completed
10832
10833         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10834         BKFREE=$(calc_osc_kbytes kbytesfree)
10835         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10836
10837         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10838         DFTOTAL=`echo $STRING | cut -d, -f1`
10839         DFUSED=`echo $STRING  | cut -d, -f2`
10840         DFAVAIL=`echo $STRING | cut -d, -f3`
10841         DFFREE=$(($DFTOTAL - $DFUSED))
10842
10843         ALLOWANCE=$((64 * $OSTCOUNT))
10844
10845         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10846            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10847                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10848         fi
10849         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10850            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10851                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10852         fi
10853         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10854            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10855                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10856         fi
10857 }
10858 run_test 79 "df report consistency check ======================="
10859
10860 test_80() { # bug 10718
10861         remote_ost_nodsh && skip "remote OST with nodsh"
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863
10864         # relax strong synchronous semantics for slow backends like ZFS
10865         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10866                 local soc="obdfilter.*.sync_lock_cancel"
10867                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10868
10869                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10870                 if [ -z "$save" ]; then
10871                         soc="obdfilter.*.sync_on_lock_cancel"
10872                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10873                 fi
10874
10875                 if [ "$save" != "never" ]; then
10876                         local hosts=$(comma_list $(osts_nodes))
10877
10878                         do_nodes $hosts $LCTL set_param $soc=never
10879                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10880                 fi
10881         fi
10882
10883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10884         sync; sleep 1; sync
10885         local before=$(date +%s)
10886         cancel_lru_locks osc
10887         local after=$(date +%s)
10888         local diff=$((after - before))
10889         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10890
10891         rm -f $DIR/$tfile
10892 }
10893 run_test 80 "Page eviction is equally fast at high offsets too"
10894
10895 test_81a() { # LU-456
10896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10897         remote_ost_nodsh && skip "remote OST with nodsh"
10898
10899         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10900         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10901         do_facet ost1 lctl set_param fail_loc=0x80000228
10902
10903         # write should trigger a retry and success
10904         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10905         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10906         RC=$?
10907         if [ $RC -ne 0 ] ; then
10908                 error "write should success, but failed for $RC"
10909         fi
10910 }
10911 run_test 81a "OST should retry write when get -ENOSPC ==============="
10912
10913 test_81b() { # LU-456
10914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10915         remote_ost_nodsh && skip "remote OST with nodsh"
10916
10917         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10918         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10919         do_facet ost1 lctl set_param fail_loc=0x228
10920
10921         # write should retry several times and return -ENOSPC finally
10922         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10923         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10924         RC=$?
10925         ENOSPC=28
10926         if [ $RC -ne $ENOSPC ] ; then
10927                 error "dd should fail for -ENOSPC, but succeed."
10928         fi
10929 }
10930 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10931
10932 test_99() {
10933         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10934
10935         test_mkdir $DIR/$tdir.cvsroot
10936         chown $RUNAS_ID $DIR/$tdir.cvsroot
10937
10938         cd $TMP
10939         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10940
10941         cd /etc/init.d
10942         # some versions of cvs import exit(1) when asked to import links or
10943         # files they can't read.  ignore those files.
10944         local toignore=$(find . -type l -printf '-I %f\n' -o \
10945                          ! -perm /4 -printf '-I %f\n')
10946         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10947                 $tdir.reposname vtag rtag
10948
10949         cd $DIR
10950         test_mkdir $DIR/$tdir.reposname
10951         chown $RUNAS_ID $DIR/$tdir.reposname
10952         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10953
10954         cd $DIR/$tdir.reposname
10955         $RUNAS touch foo99
10956         $RUNAS cvs add -m 'addmsg' foo99
10957         $RUNAS cvs update
10958         $RUNAS cvs commit -m 'nomsg' foo99
10959         rm -fr $DIR/$tdir.cvsroot
10960 }
10961 run_test 99 "cvs strange file/directory operations"
10962
10963 test_100() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965         [[ "$NETTYPE" =~ tcp ]] ||
10966                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10967         remote_ost_nodsh && skip "remote OST with nodsh"
10968         remote_mds_nodsh && skip "remote MDS with nodsh"
10969         remote_servers ||
10970                 skip "useless for local single node setup"
10971
10972         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10973                 [ "$PROT" != "tcp" ] && continue
10974                 RPORT=$(echo $REMOTE | cut -d: -f2)
10975                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10976
10977                 rc=0
10978                 LPORT=`echo $LOCAL | cut -d: -f2`
10979                 if [ $LPORT -ge 1024 ]; then
10980                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10981                         netstat -tna
10982                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10983                 fi
10984         done
10985         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10986 }
10987 run_test 100 "check local port using privileged port ==========="
10988
10989 function get_named_value()
10990 {
10991     local tag=$1
10992
10993     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10994 }
10995
10996 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10997                    awk '/^max_cached_mb/ { print $2 }')
10998
10999 cleanup_101a() {
11000         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11001         trap 0
11002 }
11003
11004 test_101a() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006
11007         local s
11008         local discard
11009         local nreads=10000
11010         local cache_limit=32
11011
11012         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11013         trap cleanup_101a EXIT
11014         $LCTL set_param -n llite.*.read_ahead_stats=0
11015         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11016
11017         #
11018         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11019         #
11020         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11021         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11022
11023         discard=0
11024         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11025                    get_named_value 'read.but.discarded'); do
11026                         discard=$(($discard + $s))
11027         done
11028         cleanup_101a
11029
11030         $LCTL get_param osc.*-osc*.rpc_stats
11031         $LCTL get_param llite.*.read_ahead_stats
11032
11033         # Discard is generally zero, but sometimes a few random reads line up
11034         # and trigger larger readahead, which is wasted & leads to discards.
11035         if [[ $(($discard)) -gt $nreads ]]; then
11036                 error "too many ($discard) discarded pages"
11037         fi
11038         rm -f $DIR/$tfile || true
11039 }
11040 run_test 101a "check read-ahead for random reads"
11041
11042 setup_test101bc() {
11043         test_mkdir $DIR/$tdir
11044         local ssize=$1
11045         local FILE_LENGTH=$2
11046         STRIPE_OFFSET=0
11047
11048         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11049
11050         local list=$(comma_list $(osts_nodes))
11051         set_osd_param $list '' read_cache_enable 0
11052         set_osd_param $list '' writethrough_cache_enable 0
11053
11054         trap cleanup_test101bc EXIT
11055         # prepare the read-ahead file
11056         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11057
11058         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11059                                 count=$FILE_SIZE_MB 2> /dev/null
11060
11061 }
11062
11063 cleanup_test101bc() {
11064         trap 0
11065         rm -rf $DIR/$tdir
11066         rm -f $DIR/$tfile
11067
11068         local list=$(comma_list $(osts_nodes))
11069         set_osd_param $list '' read_cache_enable 1
11070         set_osd_param $list '' writethrough_cache_enable 1
11071 }
11072
11073 calc_total() {
11074         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11075 }
11076
11077 ra_check_101() {
11078         local read_size=$1
11079         local stripe_size=$2
11080         local stride_length=$((stripe_size / read_size))
11081         local stride_width=$((stride_length * OSTCOUNT))
11082         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11083                                 (stride_width - stride_length) ))
11084         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11085                   get_named_value 'read.but.discarded' | calc_total)
11086
11087         if [[ $discard -gt $discard_limit ]]; then
11088                 $LCTL get_param llite.*.read_ahead_stats
11089                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11090         else
11091                 echo "Read-ahead success for size ${read_size}"
11092         fi
11093 }
11094
11095 test_101b() {
11096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11097         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11098
11099         local STRIPE_SIZE=1048576
11100         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11101
11102         if [ $SLOW == "yes" ]; then
11103                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11104         else
11105                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11106         fi
11107
11108         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11109
11110         # prepare the read-ahead file
11111         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11112         cancel_lru_locks osc
11113         for BIDX in 2 4 8 16 32 64 128 256
11114         do
11115                 local BSIZE=$((BIDX*4096))
11116                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11117                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11118                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11119                 $LCTL set_param -n llite.*.read_ahead_stats=0
11120                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11121                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11122                 cancel_lru_locks osc
11123                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11124         done
11125         cleanup_test101bc
11126         true
11127 }
11128 run_test 101b "check stride-io mode read-ahead ================="
11129
11130 test_101c() {
11131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11132
11133         local STRIPE_SIZE=1048576
11134         local FILE_LENGTH=$((STRIPE_SIZE*100))
11135         local nreads=10000
11136         local rsize=65536
11137         local osc_rpc_stats
11138
11139         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11140
11141         cancel_lru_locks osc
11142         $LCTL set_param osc.*.rpc_stats=0
11143         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11144         $LCTL get_param osc.*.rpc_stats
11145         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11146                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11147                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11148                 local size
11149
11150                 if [ $lines -le 20 ]; then
11151                         echo "continue debug"
11152                         continue
11153                 fi
11154                 for size in 1 2 4 8; do
11155                         local rpc=$(echo "$stats" |
11156                                     awk '($1 == "'$size':") {print $2; exit; }')
11157                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11158                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11159                 done
11160                 echo "$osc_rpc_stats check passed!"
11161         done
11162         cleanup_test101bc
11163         true
11164 }
11165 run_test 101c "check stripe_size aligned read-ahead"
11166
11167 test_101d() {
11168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11169
11170         local file=$DIR/$tfile
11171         local sz_MB=${FILESIZE_101d:-80}
11172         local ra_MB=${READAHEAD_MB:-40}
11173
11174         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11175         [ $free_MB -lt $sz_MB ] &&
11176                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11177
11178         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11179         $LFS setstripe -c -1 $file || error "setstripe failed"
11180
11181         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11182         echo Cancel LRU locks on lustre client to flush the client cache
11183         cancel_lru_locks osc
11184
11185         echo Disable read-ahead
11186         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11187         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11188         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11189         $LCTL get_param -n llite.*.max_read_ahead_mb
11190
11191         echo "Reading the test file $file with read-ahead disabled"
11192         local sz_KB=$((sz_MB * 1024 / 4))
11193         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11194         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11195         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11196                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11197
11198         echo "Cancel LRU locks on lustre client to flush the client cache"
11199         cancel_lru_locks osc
11200         echo Enable read-ahead with ${ra_MB}MB
11201         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11202
11203         echo "Reading the test file $file with read-ahead enabled"
11204         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11205                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11206
11207         echo "read-ahead disabled time read $raOFF"
11208         echo "read-ahead enabled time read $raON"
11209
11210         rm -f $file
11211         wait_delete_completed
11212
11213         # use awk for this check instead of bash because it handles decimals
11214         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11215                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11216 }
11217 run_test 101d "file read with and without read-ahead enabled"
11218
11219 test_101e() {
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221
11222         local file=$DIR/$tfile
11223         local size_KB=500  #KB
11224         local count=100
11225         local bsize=1024
11226
11227         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11228         local need_KB=$((count * size_KB))
11229         [[ $free_KB -le $need_KB ]] &&
11230                 skip_env "Need free space $need_KB, have $free_KB"
11231
11232         echo "Creating $count ${size_KB}K test files"
11233         for ((i = 0; i < $count; i++)); do
11234                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11235         done
11236
11237         echo "Cancel LRU locks on lustre client to flush the client cache"
11238         cancel_lru_locks $OSC
11239
11240         echo "Reset readahead stats"
11241         $LCTL set_param -n llite.*.read_ahead_stats=0
11242
11243         for ((i = 0; i < $count; i++)); do
11244                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11245         done
11246
11247         $LCTL get_param llite.*.max_cached_mb
11248         $LCTL get_param llite.*.read_ahead_stats
11249         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11250                      get_named_value 'misses' | calc_total)
11251
11252         for ((i = 0; i < $count; i++)); do
11253                 rm -rf $file.$i 2>/dev/null
11254         done
11255
11256         #10000 means 20% reads are missing in readahead
11257         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11258 }
11259 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11260
11261 test_101f() {
11262         which iozone || skip_env "no iozone installed"
11263
11264         local old_debug=$($LCTL get_param debug)
11265         old_debug=${old_debug#*=}
11266         $LCTL set_param debug="reada mmap"
11267
11268         # create a test file
11269         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11270
11271         echo Cancel LRU locks on lustre client to flush the client cache
11272         cancel_lru_locks osc
11273
11274         echo Reset readahead stats
11275         $LCTL set_param -n llite.*.read_ahead_stats=0
11276
11277         echo mmap read the file with small block size
11278         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11279                 > /dev/null 2>&1
11280
11281         echo checking missing pages
11282         $LCTL get_param llite.*.read_ahead_stats
11283         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11284                         get_named_value 'misses' | calc_total)
11285
11286         $LCTL set_param debug="$old_debug"
11287         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11288         rm -f $DIR/$tfile
11289 }
11290 run_test 101f "check mmap read performance"
11291
11292 test_101g_brw_size_test() {
11293         local mb=$1
11294         local pages=$((mb * 1048576 / PAGE_SIZE))
11295         local file=$DIR/$tfile
11296
11297         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11298                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11299         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11300                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11301                         return 2
11302         done
11303
11304         stack_trap "rm -f $file" EXIT
11305         $LCTL set_param -n osc.*.rpc_stats=0
11306
11307         # 10 RPCs should be enough for the test
11308         local count=10
11309         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11310                 { error "dd write ${mb} MB blocks failed"; return 3; }
11311         cancel_lru_locks osc
11312         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11313                 { error "dd write ${mb} MB blocks failed"; return 4; }
11314
11315         # calculate number of full-sized read and write RPCs
11316         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11317                 sed -n '/pages per rpc/,/^$/p' |
11318                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11319                 END { print reads,writes }'))
11320         # allow one extra full-sized read RPC for async readahead
11321         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11322                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11323         [[ ${rpcs[1]} == $count ]] ||
11324                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11325 }
11326
11327 test_101g() {
11328         remote_ost_nodsh && skip "remote OST with nodsh"
11329
11330         local rpcs
11331         local osts=$(get_facets OST)
11332         local list=$(comma_list $(osts_nodes))
11333         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11334         local brw_size="obdfilter.*.brw_size"
11335
11336         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11337
11338         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11339
11340         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11341                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11342                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11343            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11344                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11345                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11346
11347                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11348                         suffix="M"
11349
11350                 if [[ $orig_mb -lt 16 ]]; then
11351                         save_lustre_params $osts "$brw_size" > $p
11352                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11353                                 error "set 16MB RPC size failed"
11354
11355                         echo "remount client to enable new RPC size"
11356                         remount_client $MOUNT || error "remount_client failed"
11357                 fi
11358
11359                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11360                 # should be able to set brw_size=12, but no rpc_stats for that
11361                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11362         fi
11363
11364         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11365
11366         if [[ $orig_mb -lt 16 ]]; then
11367                 restore_lustre_params < $p
11368                 remount_client $MOUNT || error "remount_client restore failed"
11369         fi
11370
11371         rm -f $p $DIR/$tfile
11372 }
11373 run_test 101g "Big bulk(4/16 MiB) readahead"
11374
11375 test_101h() {
11376         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11377
11378         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11379                 error "dd 70M file failed"
11380         echo Cancel LRU locks on lustre client to flush the client cache
11381         cancel_lru_locks osc
11382
11383         echo "Reset readahead stats"
11384         $LCTL set_param -n llite.*.read_ahead_stats 0
11385
11386         echo "Read 10M of data but cross 64M bundary"
11387         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11388         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11389                      get_named_value 'misses' | calc_total)
11390         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11391         rm -f $p $DIR/$tfile
11392 }
11393 run_test 101h "Readahead should cover current read window"
11394
11395 test_101i() {
11396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11397                 error "dd 10M file failed"
11398
11399         local max_per_file_mb=$($LCTL get_param -n \
11400                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11401         cancel_lru_locks osc
11402         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11403         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11404                 error "set max_read_ahead_per_file_mb to 1 failed"
11405
11406         echo "Reset readahead stats"
11407         $LCTL set_param llite.*.read_ahead_stats=0
11408
11409         dd if=$DIR/$tfile of=/dev/null bs=2M
11410
11411         $LCTL get_param llite.*.read_ahead_stats
11412         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11413                      awk '/misses/ { print $2 }')
11414         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11415         rm -f $DIR/$tfile
11416 }
11417 run_test 101i "allow current readahead to exceed reservation"
11418
11419 test_101j() {
11420         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11421                 error "setstripe $DIR/$tfile failed"
11422         local file_size=$((1048576 * 16))
11423         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11424         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11425
11426         echo Disable read-ahead
11427         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11428
11429         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11430         for blk in $PAGE_SIZE 1048576 $file_size; do
11431                 cancel_lru_locks osc
11432                 echo "Reset readahead stats"
11433                 $LCTL set_param -n llite.*.read_ahead_stats=0
11434                 local count=$(($file_size / $blk))
11435                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11436                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11437                              get_named_value 'failed.to.fast.read' | calc_total)
11438                 $LCTL get_param -n llite.*.read_ahead_stats
11439                 [ $miss -eq $count ] || error "expected $count got $miss"
11440         done
11441
11442         rm -f $p $DIR/$tfile
11443 }
11444 run_test 101j "A complete read block should be submitted when no RA"
11445
11446 test_readahead_base() {
11447         local file=$DIR/$tfile
11448         local size=$1
11449         local iosz
11450         local ramax
11451         local ranum
11452
11453         $LCTL set_param -n llite.*.read_ahead_stats=0
11454         # The first page is not accounted into readahead
11455         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11456         iosz=$(((size + 1048575) / 1048576 * 1048576))
11457         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11458
11459         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11460         fallocate -l $size $file || error "failed to fallocate $file"
11461         cancel_lru_locks osc
11462         $MULTIOP $file or${iosz}c || error "failed to read $file"
11463         $LCTL get_param -n llite.*.read_ahead_stats
11464         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11465                 awk '/readahead.pages/ { print $7 }' | calc_total)
11466         (( $ranum <= $ramax )) ||
11467                 error "read-ahead pages is $ranum more than $ramax"
11468         rm -rf $file || error "failed to remove $file"
11469 }
11470
11471 test_101m()
11472 {
11473         local file=$DIR/$tfile
11474         local ramax
11475         local ranum
11476         local size
11477         local iosz
11478
11479         check_set_fallocate_or_skip
11480         stack_trap "rm -f $file" EXIT
11481
11482         test_readahead_base 4096
11483
11484         # file size: 16K = 16384
11485         test_readahead_base 16384
11486         test_readahead_base 16385
11487         test_readahead_base 16383
11488
11489         # file size: 1M + 1 = 1048576 + 1
11490         test_readahead_base 1048577
11491         # file size: 1M + 16K
11492         test_readahead_base $((1048576 + 16384))
11493
11494         # file size: stripe_size * (stripe_count - 1) + 16K
11495         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11496         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11497         # file size: stripe_size * stripe_count + 16K
11498         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11499         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11500         # file size: 2 * stripe_size * stripe_count + 16K
11501         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11502         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11503 }
11504 run_test 101m "read ahead for small file and last stripe of the file"
11505
11506 setup_test102() {
11507         test_mkdir $DIR/$tdir
11508         chown $RUNAS_ID $DIR/$tdir
11509         STRIPE_SIZE=65536
11510         STRIPE_OFFSET=1
11511         STRIPE_COUNT=$OSTCOUNT
11512         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11513
11514         trap cleanup_test102 EXIT
11515         cd $DIR
11516         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11517         cd $DIR/$tdir
11518         for num in 1 2 3 4; do
11519                 for count in $(seq 1 $STRIPE_COUNT); do
11520                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11521                                 local size=`expr $STRIPE_SIZE \* $num`
11522                                 local file=file"$num-$idx-$count"
11523                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11524                         done
11525                 done
11526         done
11527
11528         cd $DIR
11529         $1 tar cf $TMP/f102.tar $tdir --xattrs
11530 }
11531
11532 cleanup_test102() {
11533         trap 0
11534         rm -f $TMP/f102.tar
11535         rm -rf $DIR/d0.sanity/d102
11536 }
11537
11538 test_102a() {
11539         [ "$UID" != 0 ] && skip "must run as root"
11540         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11541                 skip_env "must have user_xattr"
11542
11543         [ -z "$(which setfattr 2>/dev/null)" ] &&
11544                 skip_env "could not find setfattr"
11545
11546         local testfile=$DIR/$tfile
11547
11548         touch $testfile
11549         echo "set/get xattr..."
11550         setfattr -n trusted.name1 -v value1 $testfile ||
11551                 error "setfattr -n trusted.name1=value1 $testfile failed"
11552         getfattr -n trusted.name1 $testfile 2> /dev/null |
11553           grep "trusted.name1=.value1" ||
11554                 error "$testfile missing trusted.name1=value1"
11555
11556         setfattr -n user.author1 -v author1 $testfile ||
11557                 error "setfattr -n user.author1=author1 $testfile failed"
11558         getfattr -n user.author1 $testfile 2> /dev/null |
11559           grep "user.author1=.author1" ||
11560                 error "$testfile missing trusted.author1=author1"
11561
11562         echo "listxattr..."
11563         setfattr -n trusted.name2 -v value2 $testfile ||
11564                 error "$testfile unable to set trusted.name2"
11565         setfattr -n trusted.name3 -v value3 $testfile ||
11566                 error "$testfile unable to set trusted.name3"
11567         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11568             grep "trusted.name" | wc -l) -eq 3 ] ||
11569                 error "$testfile missing 3 trusted.name xattrs"
11570
11571         setfattr -n user.author2 -v author2 $testfile ||
11572                 error "$testfile unable to set user.author2"
11573         setfattr -n user.author3 -v author3 $testfile ||
11574                 error "$testfile unable to set user.author3"
11575         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11576             grep "user.author" | wc -l) -eq 3 ] ||
11577                 error "$testfile missing 3 user.author xattrs"
11578
11579         echo "remove xattr..."
11580         setfattr -x trusted.name1 $testfile ||
11581                 error "$testfile error deleting trusted.name1"
11582         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11583                 error "$testfile did not delete trusted.name1 xattr"
11584
11585         setfattr -x user.author1 $testfile ||
11586                 error "$testfile error deleting user.author1"
11587         echo "set lustre special xattr ..."
11588         $LFS setstripe -c1 $testfile
11589         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11590                 awk -F "=" '/trusted.lov/ { print $2 }' )
11591         setfattr -n "trusted.lov" -v $lovea $testfile ||
11592                 error "$testfile doesn't ignore setting trusted.lov again"
11593         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11594                 error "$testfile allow setting invalid trusted.lov"
11595         rm -f $testfile
11596 }
11597 run_test 102a "user xattr test =================================="
11598
11599 check_102b_layout() {
11600         local layout="$*"
11601         local testfile=$DIR/$tfile
11602
11603         echo "test layout '$layout'"
11604         $LFS setstripe $layout $testfile || error "setstripe failed"
11605         $LFS getstripe -y $testfile
11606
11607         echo "get/set/list trusted.lov xattr ..." # b=10930
11608         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11609         [[ "$value" =~ "trusted.lov" ]] ||
11610                 error "can't get trusted.lov from $testfile"
11611         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11612                 error "getstripe failed"
11613
11614         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11615
11616         value=$(cut -d= -f2 <<<$value)
11617         # LU-13168: truncated xattr should fail if short lov_user_md header
11618         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11619                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11620         for len in $lens; do
11621                 echo "setfattr $len $testfile.2"
11622                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11623                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11624         done
11625         local stripe_size=$($LFS getstripe -S $testfile.2)
11626         local stripe_count=$($LFS getstripe -c $testfile.2)
11627         [[ $stripe_size -eq 65536 ]] ||
11628                 error "stripe size $stripe_size != 65536"
11629         [[ $stripe_count -eq $stripe_count_orig ]] ||
11630                 error "stripe count $stripe_count != $stripe_count_orig"
11631         rm $testfile $testfile.2
11632 }
11633
11634 test_102b() {
11635         [ -z "$(which setfattr 2>/dev/null)" ] &&
11636                 skip_env "could not find setfattr"
11637         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11638
11639         # check plain layout
11640         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11641
11642         # and also check composite layout
11643         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11644
11645 }
11646 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11647
11648 test_102c() {
11649         [ -z "$(which setfattr 2>/dev/null)" ] &&
11650                 skip_env "could not find setfattr"
11651         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11652
11653         # b10930: get/set/list lustre.lov xattr
11654         echo "get/set/list lustre.lov xattr ..."
11655         test_mkdir $DIR/$tdir
11656         chown $RUNAS_ID $DIR/$tdir
11657         local testfile=$DIR/$tdir/$tfile
11658         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11659                 error "setstripe failed"
11660         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11661                 error "getstripe failed"
11662         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11663         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11664
11665         local testfile2=${testfile}2
11666         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11667                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11668
11669         $RUNAS $MCREATE $testfile2
11670         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11671         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11672         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11673         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11674         [ $stripe_count -eq $STRIPECOUNT ] ||
11675                 error "stripe count $stripe_count != $STRIPECOUNT"
11676 }
11677 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11678
11679 compare_stripe_info1() {
11680         local stripe_index_all_zero=true
11681
11682         for num in 1 2 3 4; do
11683                 for count in $(seq 1 $STRIPE_COUNT); do
11684                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11685                                 local size=$((STRIPE_SIZE * num))
11686                                 local file=file"$num-$offset-$count"
11687                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11688                                 [[ $stripe_size -ne $size ]] &&
11689                                     error "$file: size $stripe_size != $size"
11690                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11691                                 # allow fewer stripes to be created, ORI-601
11692                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11693                                     error "$file: count $stripe_count != $count"
11694                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11695                                 [[ $stripe_index -ne 0 ]] &&
11696                                         stripe_index_all_zero=false
11697                         done
11698                 done
11699         done
11700         $stripe_index_all_zero &&
11701                 error "all files are being extracted starting from OST index 0"
11702         return 0
11703 }
11704
11705 have_xattrs_include() {
11706         tar --help | grep -q xattrs-include &&
11707                 echo --xattrs-include="lustre.*"
11708 }
11709
11710 test_102d() {
11711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11712         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11713
11714         XINC=$(have_xattrs_include)
11715         setup_test102
11716         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11717         cd $DIR/$tdir/$tdir
11718         compare_stripe_info1
11719 }
11720 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11721
11722 test_102f() {
11723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11724         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11725
11726         XINC=$(have_xattrs_include)
11727         setup_test102
11728         test_mkdir $DIR/$tdir.restore
11729         cd $DIR
11730         tar cf - --xattrs $tdir | tar xf - \
11731                 -C $DIR/$tdir.restore --xattrs $XINC
11732         cd $DIR/$tdir.restore/$tdir
11733         compare_stripe_info1
11734 }
11735 run_test 102f "tar copy files, not keep osts"
11736
11737 grow_xattr() {
11738         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11739                 skip "must have user_xattr"
11740         [ -z "$(which setfattr 2>/dev/null)" ] &&
11741                 skip_env "could not find setfattr"
11742         [ -z "$(which getfattr 2>/dev/null)" ] &&
11743                 skip_env "could not find getfattr"
11744
11745         local xsize=${1:-1024}  # in bytes
11746         local file=$DIR/$tfile
11747         local value="$(generate_string $xsize)"
11748         local xbig=trusted.big
11749         local toobig=$2
11750
11751         touch $file
11752         log "save $xbig on $file"
11753         if [ -z "$toobig" ]
11754         then
11755                 setfattr -n $xbig -v $value $file ||
11756                         error "saving $xbig on $file failed"
11757         else
11758                 setfattr -n $xbig -v $value $file &&
11759                         error "saving $xbig on $file succeeded"
11760                 return 0
11761         fi
11762
11763         local orig=$(get_xattr_value $xbig $file)
11764         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11765
11766         local xsml=trusted.sml
11767         log "save $xsml on $file"
11768         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11769
11770         local new=$(get_xattr_value $xbig $file)
11771         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11772
11773         log "grow $xsml on $file"
11774         setfattr -n $xsml -v "$value" $file ||
11775                 error "growing $xsml on $file failed"
11776
11777         new=$(get_xattr_value $xbig $file)
11778         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11779         log "$xbig still valid after growing $xsml"
11780
11781         rm -f $file
11782 }
11783
11784 test_102h() { # bug 15777
11785         grow_xattr 1024
11786 }
11787 run_test 102h "grow xattr from inside inode to external block"
11788
11789 test_102ha() {
11790         large_xattr_enabled || skip_env "ea_inode feature disabled"
11791
11792         echo "setting xattr of max xattr size: $(max_xattr_size)"
11793         grow_xattr $(max_xattr_size)
11794
11795         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11796         echo "This should fail:"
11797         grow_xattr $(($(max_xattr_size) + 10)) 1
11798 }
11799 run_test 102ha "grow xattr from inside inode to external inode"
11800
11801 test_102i() { # bug 17038
11802         [ -z "$(which getfattr 2>/dev/null)" ] &&
11803                 skip "could not find getfattr"
11804
11805         touch $DIR/$tfile
11806         ln -s $DIR/$tfile $DIR/${tfile}link
11807         getfattr -n trusted.lov $DIR/$tfile ||
11808                 error "lgetxattr on $DIR/$tfile failed"
11809         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11810                 grep -i "no such attr" ||
11811                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11812         rm -f $DIR/$tfile $DIR/${tfile}link
11813 }
11814 run_test 102i "lgetxattr test on symbolic link ============"
11815
11816 test_102j() {
11817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11818         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11819
11820         XINC=$(have_xattrs_include)
11821         setup_test102 "$RUNAS"
11822         chown $RUNAS_ID $DIR/$tdir
11823         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11824         cd $DIR/$tdir/$tdir
11825         compare_stripe_info1 "$RUNAS"
11826 }
11827 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11828
11829 test_102k() {
11830         [ -z "$(which setfattr 2>/dev/null)" ] &&
11831                 skip "could not find setfattr"
11832
11833         touch $DIR/$tfile
11834         # b22187 just check that does not crash for regular file.
11835         setfattr -n trusted.lov $DIR/$tfile
11836         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11837         local test_kdir=$DIR/$tdir
11838         test_mkdir $test_kdir
11839         local default_size=$($LFS getstripe -S $test_kdir)
11840         local default_count=$($LFS getstripe -c $test_kdir)
11841         local default_offset=$($LFS getstripe -i $test_kdir)
11842         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11843                 error 'dir setstripe failed'
11844         setfattr -n trusted.lov $test_kdir
11845         local stripe_size=$($LFS getstripe -S $test_kdir)
11846         local stripe_count=$($LFS getstripe -c $test_kdir)
11847         local stripe_offset=$($LFS getstripe -i $test_kdir)
11848         [ $stripe_size -eq $default_size ] ||
11849                 error "stripe size $stripe_size != $default_size"
11850         [ $stripe_count -eq $default_count ] ||
11851                 error "stripe count $stripe_count != $default_count"
11852         [ $stripe_offset -eq $default_offset ] ||
11853                 error "stripe offset $stripe_offset != $default_offset"
11854         rm -rf $DIR/$tfile $test_kdir
11855 }
11856 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11857
11858 test_102l() {
11859         [ -z "$(which getfattr 2>/dev/null)" ] &&
11860                 skip "could not find getfattr"
11861
11862         # LU-532 trusted. xattr is invisible to non-root
11863         local testfile=$DIR/$tfile
11864
11865         touch $testfile
11866
11867         echo "listxattr as user..."
11868         chown $RUNAS_ID $testfile
11869         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11870             grep -q "trusted" &&
11871                 error "$testfile trusted xattrs are user visible"
11872
11873         return 0;
11874 }
11875 run_test 102l "listxattr size test =================================="
11876
11877 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11878         local path=$DIR/$tfile
11879         touch $path
11880
11881         listxattr_size_check $path || error "listattr_size_check $path failed"
11882 }
11883 run_test 102m "Ensure listxattr fails on small bufffer ========"
11884
11885 cleanup_test102
11886
11887 getxattr() { # getxattr path name
11888         # Return the base64 encoding of the value of xattr name on path.
11889         local path=$1
11890         local name=$2
11891
11892         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11893         # file: $path
11894         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11895         #
11896         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11897
11898         getfattr --absolute-names --encoding=base64 --name=$name $path |
11899                 awk -F= -v name=$name '$1 == name {
11900                         print substr($0, index($0, "=") + 1);
11901         }'
11902 }
11903
11904 test_102n() { # LU-4101 mdt: protect internal xattrs
11905         [ -z "$(which setfattr 2>/dev/null)" ] &&
11906                 skip "could not find setfattr"
11907         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11908         then
11909                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11910         fi
11911
11912         local file0=$DIR/$tfile.0
11913         local file1=$DIR/$tfile.1
11914         local xattr0=$TMP/$tfile.0
11915         local xattr1=$TMP/$tfile.1
11916         local namelist="lov lma lmv link fid version som hsm"
11917         local name
11918         local value
11919
11920         rm -rf $file0 $file1 $xattr0 $xattr1
11921         touch $file0 $file1
11922
11923         # Get 'before' xattrs of $file1.
11924         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11925
11926         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11927                 namelist+=" lfsck_namespace"
11928         for name in $namelist; do
11929                 # Try to copy xattr from $file0 to $file1.
11930                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11931
11932                 setfattr --name=trusted.$name --value="$value" $file1 ||
11933                         error "setxattr 'trusted.$name' failed"
11934
11935                 # Try to set a garbage xattr.
11936                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11937
11938                 if [[ x$name == "xlov" ]]; then
11939                         setfattr --name=trusted.lov --value="$value" $file1 &&
11940                         error "setxattr invalid 'trusted.lov' success"
11941                 else
11942                         setfattr --name=trusted.$name --value="$value" $file1 ||
11943                                 error "setxattr invalid 'trusted.$name' failed"
11944                 fi
11945
11946                 # Try to remove the xattr from $file1. We don't care if this
11947                 # appears to succeed or fail, we just don't want there to be
11948                 # any changes or crashes.
11949                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11950         done
11951
11952         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11953         then
11954                 name="lfsck_ns"
11955                 # Try to copy xattr from $file0 to $file1.
11956                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11957
11958                 setfattr --name=trusted.$name --value="$value" $file1 ||
11959                         error "setxattr 'trusted.$name' failed"
11960
11961                 # Try to set a garbage xattr.
11962                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11963
11964                 setfattr --name=trusted.$name --value="$value" $file1 ||
11965                         error "setxattr 'trusted.$name' failed"
11966
11967                 # Try to remove the xattr from $file1. We don't care if this
11968                 # appears to succeed or fail, we just don't want there to be
11969                 # any changes or crashes.
11970                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11971         fi
11972
11973         # Get 'after' xattrs of file1.
11974         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11975
11976         if ! diff $xattr0 $xattr1; then
11977                 error "before and after xattrs of '$file1' differ"
11978         fi
11979
11980         rm -rf $file0 $file1 $xattr0 $xattr1
11981
11982         return 0
11983 }
11984 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11985
11986 test_102p() { # LU-4703 setxattr did not check ownership
11987         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11988                 skip "MDS needs to be at least 2.5.56"
11989
11990         local testfile=$DIR/$tfile
11991
11992         touch $testfile
11993
11994         echo "setfacl as user..."
11995         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11996         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11997
11998         echo "setfattr as user..."
11999         setfacl -m "u:$RUNAS_ID:---" $testfile
12000         $RUNAS setfattr -x system.posix_acl_access $testfile
12001         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12002 }
12003 run_test 102p "check setxattr(2) correctly fails without permission"
12004
12005 test_102q() {
12006         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12007                 skip "MDS needs to be at least 2.6.92"
12008
12009         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12010 }
12011 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12012
12013 test_102r() {
12014         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12015                 skip "MDS needs to be at least 2.6.93"
12016
12017         touch $DIR/$tfile || error "touch"
12018         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12019         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12020         rm $DIR/$tfile || error "rm"
12021
12022         #normal directory
12023         mkdir -p $DIR/$tdir || error "mkdir"
12024         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12025         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12026         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12027                 error "$testfile error deleting user.author1"
12028         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12029                 grep "user.$(basename $tdir)" &&
12030                 error "$tdir did not delete user.$(basename $tdir)"
12031         rmdir $DIR/$tdir || error "rmdir"
12032
12033         #striped directory
12034         test_mkdir $DIR/$tdir
12035         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12036         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12037         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12038                 error "$testfile error deleting user.author1"
12039         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12040                 grep "user.$(basename $tdir)" &&
12041                 error "$tdir did not delete user.$(basename $tdir)"
12042         rmdir $DIR/$tdir || error "rm striped dir"
12043 }
12044 run_test 102r "set EAs with empty values"
12045
12046 test_102s() {
12047         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12048                 skip "MDS needs to be at least 2.11.52"
12049
12050         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12051
12052         save_lustre_params client "llite.*.xattr_cache" > $save
12053
12054         for cache in 0 1; do
12055                 lctl set_param llite.*.xattr_cache=$cache
12056
12057                 rm -f $DIR/$tfile
12058                 touch $DIR/$tfile || error "touch"
12059                 for prefix in lustre security system trusted user; do
12060                         # Note getxattr() may fail with 'Operation not
12061                         # supported' or 'No such attribute' depending
12062                         # on prefix and cache.
12063                         getfattr -n $prefix.n102s $DIR/$tfile &&
12064                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12065                 done
12066         done
12067
12068         restore_lustre_params < $save
12069 }
12070 run_test 102s "getting nonexistent xattrs should fail"
12071
12072 test_102t() {
12073         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12074                 skip "MDS needs to be at least 2.11.52"
12075
12076         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12077
12078         save_lustre_params client "llite.*.xattr_cache" > $save
12079
12080         for cache in 0 1; do
12081                 lctl set_param llite.*.xattr_cache=$cache
12082
12083                 for buf_size in 0 256; do
12084                         rm -f $DIR/$tfile
12085                         touch $DIR/$tfile || error "touch"
12086                         setfattr -n user.multiop $DIR/$tfile
12087                         $MULTIOP $DIR/$tfile oa$buf_size ||
12088                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12089                 done
12090         done
12091
12092         restore_lustre_params < $save
12093 }
12094 run_test 102t "zero length xattr values handled correctly"
12095
12096 run_acl_subtest()
12097 {
12098         local test=$LUSTRE/tests/acl/$1.test
12099         local tmp=$(mktemp -t $1-XXXXXX).test
12100         local bin=$2
12101         local dmn=$3
12102         local grp=$4
12103         local nbd=$5
12104         export LANG=C
12105
12106
12107         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12108         local sedgroups="-e s/:users/:$grp/g"
12109         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12110
12111         sed $sedusers $sedgroups < $test > $tmp
12112         stack_trap "rm -f $tmp"
12113         [[ -s $tmp ]] || error "sed failed to create test script"
12114
12115         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12116         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12117 }
12118
12119 test_103a() {
12120         [ "$UID" != 0 ] && skip "must run as root"
12121         $GSS && skip_env "could not run under gss"
12122         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12123                 skip_env "must have acl enabled"
12124         which setfacl || skip_env "could not find setfacl"
12125         remote_mds_nodsh && skip "remote MDS with nodsh"
12126
12127         ACLBIN=${ACLBIN:-"bin"}
12128         ACLDMN=${ACLDMN:-"daemon"}
12129         ACLGRP=${ACLGRP:-"users"}
12130         ACLNBD=${ACLNBD:-"nobody"}
12131
12132         if ! id $ACLBIN ||
12133            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12134                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12135                 ACLBIN=$USER0
12136                 if ! id $ACLBIN ; then
12137                         cat /etc/passwd
12138                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12139                 fi
12140         fi
12141         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12142            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12143                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12144                 ACLDMN=$USER1
12145                 if ! id $ACLDMN ; then
12146                         cat /etc/passwd
12147                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12148                 fi
12149         fi
12150         if ! getent group $ACLGRP; then
12151                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12152                 ACLGRP="$TSTUSR"
12153                 if ! getent group $ACLGRP; then
12154                         echo "cannot find group '$ACLGRP', adding it"
12155                         cat /etc/group
12156                         add_group 60000 $ACLGRP
12157                 fi
12158         fi
12159
12160         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12161         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12162         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12163
12164         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12165                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12166                 ACLGRP="$TSTUSR"
12167                 if ! getent group $ACLGRP; then
12168                         echo "cannot find group '$ACLGRP', adding it"
12169                         cat /etc/group
12170                         add_group 60000 $ACLGRP
12171                 fi
12172                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12173                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12174                         cat /etc/group
12175                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12176                 fi
12177         fi
12178
12179         gpasswd -a $ACLDMN $ACLBIN ||
12180                 error "setting client group failed"             # LU-5641
12181         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12182                 error "setting MDS group failed"                # LU-5641
12183
12184         declare -a identity_old
12185
12186         for num in $(seq $MDSCOUNT); do
12187                 switch_identity $num true || identity_old[$num]=$?
12188         done
12189
12190         SAVE_UMASK=$(umask)
12191         umask 0022
12192         mkdir -p $DIR/$tdir
12193         cd $DIR/$tdir
12194
12195         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12196         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12197         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12198         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12199         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12200         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12201         if ! id -u $ACLNBD ||
12202            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12203                 ACLNBD="nfsnobody"
12204                 if ! id -u $ACLNBD; then
12205                         ACLNBD=""
12206                 fi
12207         fi
12208         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12209                 add_group $(id -u $ACLNBD) $ACLNBD
12210                 if ! getent group $ACLNBD; then
12211                         ACLNBD=""
12212                 fi
12213         fi
12214         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12215            [[ -n "$ACLNBD" ]] && which setfattr; then
12216                 run_acl_subtest permissions_xattr \
12217                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12218         elif [[ -z "$ACLNBD" ]]; then
12219                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12220         else
12221                 echo "skip 'permission_xattr' test - missing setfattr command"
12222         fi
12223         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12224
12225         # inheritance test got from HP
12226         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12227         chmod +x make-tree || error "chmod +x failed"
12228         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12229         rm -f make-tree
12230
12231         echo "LU-974 ignore umask when acl is enabled..."
12232         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12233         if [ $MDSCOUNT -ge 2 ]; then
12234                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12235         fi
12236
12237         echo "LU-2561 newly created file is same size as directory..."
12238         if [ "$mds1_FSTYPE" != "zfs" ]; then
12239                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12240         else
12241                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12242         fi
12243
12244         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12245
12246         cd $SAVE_PWD
12247         umask $SAVE_UMASK
12248
12249         for num in $(seq $MDSCOUNT); do
12250                 if [ "${identity_old[$num]}" = 1 ]; then
12251                         switch_identity $num false || identity_old[$num]=$?
12252                 fi
12253         done
12254 }
12255 run_test 103a "acl test"
12256
12257 test_103b() {
12258         declare -a pids
12259         local U
12260
12261         for U in {0..511}; do
12262                 {
12263                 local O=$(printf "%04o" $U)
12264
12265                 umask $(printf "%04o" $((511 ^ $O)))
12266                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12267                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12268
12269                 (( $S == ($O & 0666) )) ||
12270                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12271
12272                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12273                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12274                 (( $S == ($O & 0666) )) ||
12275                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12276
12277                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12278                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12279                 (( $S == ($O & 0666) )) ||
12280                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12281                 rm -f $DIR/$tfile.[smp]$0
12282                 } &
12283                 local pid=$!
12284
12285                 # limit the concurrently running threads to 64. LU-11878
12286                 local idx=$((U % 64))
12287                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12288                 pids[idx]=$pid
12289         done
12290         wait
12291 }
12292 run_test 103b "umask lfs setstripe"
12293
12294 test_103c() {
12295         mkdir -p $DIR/$tdir
12296         cp -rp $DIR/$tdir $DIR/$tdir.bak
12297
12298         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12299                 error "$DIR/$tdir shouldn't contain default ACL"
12300         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12301                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12302         true
12303 }
12304 run_test 103c "'cp -rp' won't set empty acl"
12305
12306 test_103e() {
12307         local numacl
12308         local fileacl
12309         local saved_debug=$($LCTL get_param -n debug)
12310
12311         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12312                 skip "MDS needs to be at least 2.14.52"
12313
12314         large_xattr_enabled || skip_env "ea_inode feature disabled"
12315
12316         mkdir -p $DIR/$tdir
12317         # add big LOV EA to cause reply buffer overflow earlier
12318         $LFS setstripe -C 1000 $DIR/$tdir
12319         lctl set_param mdc.*-mdc*.stats=clear
12320
12321         $LCTL set_param debug=0
12322         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12323         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12324
12325         # add a large number of default ACLs (expect 8000+ for 2.13+)
12326         for U in {2..7000}; do
12327                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12328                         error "Able to add just $U default ACLs"
12329         done
12330         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12331         echo "$numacl default ACLs created"
12332
12333         stat $DIR/$tdir || error "Cannot stat directory"
12334         # check file creation
12335         touch $DIR/$tdir/$tfile ||
12336                 error "failed to create $tfile with $numacl default ACLs"
12337         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12338         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12339         echo "$fileacl ACLs were inherited"
12340         (( $fileacl == $numacl )) ||
12341                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12342         # check that new ACLs creation adds new ACLs to inherited ACLs
12343         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12344                 error "Cannot set new ACL"
12345         numacl=$((numacl + 1))
12346         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12347         (( $fileacl == $numacl )) ||
12348                 error "failed to add new ACL: $fileacl != $numacl as expected"
12349         # adds more ACLs to a file to reach their maximum at 8000+
12350         numacl=0
12351         for U in {20000..25000}; do
12352                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12353                 numacl=$((numacl + 1))
12354         done
12355         echo "Added $numacl more ACLs to the file"
12356         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12357         echo "Total $fileacl ACLs in file"
12358         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12359         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12360         rmdir $DIR/$tdir || error "Cannot remove directory"
12361 }
12362 run_test 103e "inheritance of big amount of default ACLs"
12363
12364 test_103f() {
12365         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12366                 skip "MDS needs to be at least 2.14.51"
12367
12368         large_xattr_enabled || skip_env "ea_inode feature disabled"
12369
12370         # enable changelog to consume more internal MDD buffers
12371         changelog_register
12372
12373         mkdir -p $DIR/$tdir
12374         # add big LOV EA
12375         $LFS setstripe -C 1000 $DIR/$tdir
12376         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12377         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12378         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12379         rmdir $DIR/$tdir || error "Cannot remove directory"
12380 }
12381 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12382
12383 test_104a() {
12384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12385
12386         touch $DIR/$tfile
12387         lfs df || error "lfs df failed"
12388         lfs df -ih || error "lfs df -ih failed"
12389         lfs df -h $DIR || error "lfs df -h $DIR failed"
12390         lfs df -i $DIR || error "lfs df -i $DIR failed"
12391         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12392         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12393
12394         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12395         lctl --device %$OSC deactivate
12396         lfs df || error "lfs df with deactivated OSC failed"
12397         lctl --device %$OSC activate
12398         # wait the osc back to normal
12399         wait_osc_import_ready client ost
12400
12401         lfs df || error "lfs df with reactivated OSC failed"
12402         rm -f $DIR/$tfile
12403 }
12404 run_test 104a "lfs df [-ih] [path] test ========================="
12405
12406 test_104b() {
12407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12408         [ $RUNAS_ID -eq $UID ] &&
12409                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12410
12411         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12412                         grep "Permission denied" | wc -l)))
12413         if [ $denied_cnt -ne 0 ]; then
12414                 error "lfs check servers test failed"
12415         fi
12416 }
12417 run_test 104b "$RUNAS lfs check servers test ===================="
12418
12419 #
12420 # Verify $1 is within range of $2.
12421 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12422 # $1 is <= 2% of $2. Else Fail.
12423 #
12424 value_in_range() {
12425         # Strip all units (M, G, T)
12426         actual=$(echo $1 | tr -d A-Z)
12427         expect=$(echo $2 | tr -d A-Z)
12428
12429         expect_lo=$(($expect * 98 / 100)) # 2% below
12430         expect_hi=$(($expect * 102 / 100)) # 2% above
12431
12432         # permit 2% drift above and below
12433         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12434 }
12435
12436 test_104c() {
12437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12438         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12439
12440         local ost_param="osd-zfs.$FSNAME-OST0000."
12441         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12442         local ofacets=$(get_facets OST)
12443         local mfacets=$(get_facets MDS)
12444         local saved_ost_blocks=
12445         local saved_mdt_blocks=
12446
12447         echo "Before recordsize change"
12448         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12449         df=($(df -h | grep "$MOUNT"$))
12450
12451         # For checking.
12452         echo "lfs output : ${lfs_df[*]}"
12453         echo "df  output : ${df[*]}"
12454
12455         for facet in ${ofacets//,/ }; do
12456                 if [ -z $saved_ost_blocks ]; then
12457                         saved_ost_blocks=$(do_facet $facet \
12458                                 lctl get_param -n $ost_param.blocksize)
12459                         echo "OST Blocksize: $saved_ost_blocks"
12460                 fi
12461                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12462                 do_facet $facet zfs set recordsize=32768 $ost
12463         done
12464
12465         # BS too small. Sufficient for functional testing.
12466         for facet in ${mfacets//,/ }; do
12467                 if [ -z $saved_mdt_blocks ]; then
12468                         saved_mdt_blocks=$(do_facet $facet \
12469                                 lctl get_param -n $mdt_param.blocksize)
12470                         echo "MDT Blocksize: $saved_mdt_blocks"
12471                 fi
12472                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12473                 do_facet $facet zfs set recordsize=32768 $mdt
12474         done
12475
12476         # Give new values chance to reflect change
12477         sleep 2
12478
12479         echo "After recordsize change"
12480         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12481         df_after=($(df -h | grep "$MOUNT"$))
12482
12483         # For checking.
12484         echo "lfs output : ${lfs_df_after[*]}"
12485         echo "df  output : ${df_after[*]}"
12486
12487         # Verify lfs df
12488         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12489                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12490         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12491                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12492         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12493                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12494
12495         # Verify df
12496         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12497                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12498         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12499                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12500         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12501                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12502
12503         # Restore MDT recordize back to original
12504         for facet in ${mfacets//,/ }; do
12505                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12506                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12507         done
12508
12509         # Restore OST recordize back to original
12510         for facet in ${ofacets//,/ }; do
12511                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12512                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12513         done
12514
12515         return 0
12516 }
12517 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12518
12519 test_104d() {
12520         (( $RUNAS_ID != $UID )) ||
12521                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12522
12523         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12524                 skip "lustre version doesn't support lctl dl with non-root"
12525
12526         # debugfs only allows root users to access files, so the
12527         # previous move of the "devices" file to debugfs broke
12528         # "lctl dl" for non-root users. The LU-9680 Netlink
12529         # interface again allows non-root users to list devices.
12530         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12531                 error "lctl dl doesn't work for non root"
12532
12533         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12534         [ "$ost_count" -eq $OSTCOUNT ]  ||
12535                 error "lctl dl reports wrong number of OST devices"
12536
12537         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12538         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12539                 error "lctl dl reports wrong number of MDT devices"
12540 }
12541 run_test 104d "$RUNAS lctl dl test"
12542
12543 test_105a() {
12544         # doesn't work on 2.4 kernels
12545         touch $DIR/$tfile
12546         if $(flock_is_enabled); then
12547                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12548         else
12549                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12550         fi
12551         rm -f $DIR/$tfile
12552 }
12553 run_test 105a "flock when mounted without -o flock test ========"
12554
12555 test_105b() {
12556         touch $DIR/$tfile
12557         if $(flock_is_enabled); then
12558                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12559         else
12560                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12561         fi
12562         rm -f $DIR/$tfile
12563 }
12564 run_test 105b "fcntl when mounted without -o flock test ========"
12565
12566 test_105c() {
12567         touch $DIR/$tfile
12568         if $(flock_is_enabled); then
12569                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12570         else
12571                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12572         fi
12573         rm -f $DIR/$tfile
12574 }
12575 run_test 105c "lockf when mounted without -o flock test"
12576
12577 test_105d() { # bug 15924
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579
12580         test_mkdir $DIR/$tdir
12581         flock_is_enabled || skip_env "mount w/o flock enabled"
12582         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12583         $LCTL set_param fail_loc=0x80000315
12584         flocks_test 2 $DIR/$tdir
12585 }
12586 run_test 105d "flock race (should not freeze) ========"
12587
12588 test_105e() { # bug 22660 && 22040
12589         flock_is_enabled || skip_env "mount w/o flock enabled"
12590
12591         touch $DIR/$tfile
12592         flocks_test 3 $DIR/$tfile
12593 }
12594 run_test 105e "Two conflicting flocks from same process"
12595
12596 test_106() { #bug 10921
12597         test_mkdir $DIR/$tdir
12598         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12599         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12600 }
12601 run_test 106 "attempt exec of dir followed by chown of that dir"
12602
12603 test_107() {
12604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12605
12606         CDIR=`pwd`
12607         local file=core
12608
12609         cd $DIR
12610         rm -f $file
12611
12612         local save_pattern=$(sysctl -n kernel.core_pattern)
12613         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12614         sysctl -w kernel.core_pattern=$file
12615         sysctl -w kernel.core_uses_pid=0
12616
12617         ulimit -c unlimited
12618         sleep 60 &
12619         SLEEPPID=$!
12620
12621         sleep 1
12622
12623         kill -s 11 $SLEEPPID
12624         wait $SLEEPPID
12625         if [ -e $file ]; then
12626                 size=`stat -c%s $file`
12627                 [ $size -eq 0 ] && error "Fail to create core file $file"
12628         else
12629                 error "Fail to create core file $file"
12630         fi
12631         rm -f $file
12632         sysctl -w kernel.core_pattern=$save_pattern
12633         sysctl -w kernel.core_uses_pid=$save_uses_pid
12634         cd $CDIR
12635 }
12636 run_test 107 "Coredump on SIG"
12637
12638 test_110() {
12639         test_mkdir $DIR/$tdir
12640         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12641         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12642                 error "mkdir with 256 char should fail, but did not"
12643         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12644                 error "create with 255 char failed"
12645         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12646                 error "create with 256 char should fail, but did not"
12647
12648         ls -l $DIR/$tdir
12649         rm -rf $DIR/$tdir
12650 }
12651 run_test 110 "filename length checking"
12652
12653 test_116a() { # was previously test_116()
12654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12655         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12656         remote_mds_nodsh && skip "remote MDS with nodsh"
12657
12658         echo -n "Free space priority "
12659         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12660                 head -n1
12661         declare -a AVAIL
12662         free_min_max
12663
12664         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12665         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12666         stack_trap simple_cleanup_common
12667
12668         # Check if we need to generate uneven OSTs
12669         test_mkdir -p $DIR/$tdir/OST${MINI}
12670         local FILL=$((MINV / 4))
12671         local DIFF=$((MAXV - MINV))
12672         local DIFF2=$((DIFF * 100 / MINV))
12673
12674         local threshold=$(do_facet $SINGLEMDS \
12675                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12676         threshold=${threshold%%%}
12677         echo -n "Check for uneven OSTs: "
12678         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12679
12680         if [[ $DIFF2 -gt $threshold ]]; then
12681                 echo "ok"
12682                 echo "Don't need to fill OST$MINI"
12683         else
12684                 # generate uneven OSTs. Write 2% over the QOS threshold value
12685                 echo "no"
12686                 DIFF=$((threshold - DIFF2 + 2))
12687                 DIFF2=$((MINV * DIFF / 100))
12688                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12689                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12690                         error "setstripe failed"
12691                 DIFF=$((DIFF2 / 2048))
12692                 i=0
12693                 while [ $i -lt $DIFF ]; do
12694                         i=$((i + 1))
12695                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12696                                 bs=2M count=1 2>/dev/null
12697                         echo -n .
12698                 done
12699                 echo .
12700                 sync
12701                 sleep_maxage
12702                 free_min_max
12703         fi
12704
12705         DIFF=$((MAXV - MINV))
12706         DIFF2=$((DIFF * 100 / MINV))
12707         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12708         if [ $DIFF2 -gt $threshold ]; then
12709                 echo "ok"
12710         else
12711                 skip "QOS imbalance criteria not met"
12712         fi
12713
12714         MINI1=$MINI
12715         MINV1=$MINV
12716         MAXI1=$MAXI
12717         MAXV1=$MAXV
12718
12719         # now fill using QOS
12720         $LFS setstripe -c 1 $DIR/$tdir
12721         FILL=$((FILL / 200))
12722         if [ $FILL -gt 600 ]; then
12723                 FILL=600
12724         fi
12725         echo "writing $FILL files to QOS-assigned OSTs"
12726         i=0
12727         while [ $i -lt $FILL ]; do
12728                 i=$((i + 1))
12729                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12730                         count=1 2>/dev/null
12731                 echo -n .
12732         done
12733         echo "wrote $i 200k files"
12734         sync
12735         sleep_maxage
12736
12737         echo "Note: free space may not be updated, so measurements might be off"
12738         free_min_max
12739         DIFF2=$((MAXV - MINV))
12740         echo "free space delta: orig $DIFF final $DIFF2"
12741         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12742         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12743         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12744         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12745         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12746         if [[ $DIFF -gt 0 ]]; then
12747                 FILL=$((DIFF2 * 100 / DIFF - 100))
12748                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12749         fi
12750
12751         # Figure out which files were written where
12752         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12753                awk '/'$MINI1': / {print $2; exit}')
12754         echo $UUID
12755         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12756         echo "$MINC files created on smaller OST $MINI1"
12757         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12758                awk '/'$MAXI1': / {print $2; exit}')
12759         echo $UUID
12760         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12761         echo "$MAXC files created on larger OST $MAXI1"
12762         if [[ $MINC -gt 0 ]]; then
12763                 FILL=$((MAXC * 100 / MINC - 100))
12764                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12765         fi
12766         [[ $MAXC -gt $MINC ]] ||
12767                 error_ignore LU-9 "stripe QOS didn't balance free space"
12768 }
12769 run_test 116a "stripe QOS: free space balance ==================="
12770
12771 test_116b() { # LU-2093
12772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12773         remote_mds_nodsh && skip "remote MDS with nodsh"
12774
12775 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12776         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12777                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12778         [ -z "$old_rr" ] && skip "no QOS"
12779         do_facet $SINGLEMDS lctl set_param \
12780                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12781         mkdir -p $DIR/$tdir
12782         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12783         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12784         do_facet $SINGLEMDS lctl set_param fail_loc=0
12785         rm -rf $DIR/$tdir
12786         do_facet $SINGLEMDS lctl set_param \
12787                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12788 }
12789 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12790
12791 test_117() # bug 10891
12792 {
12793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12794
12795         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12796         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12797         lctl set_param fail_loc=0x21e
12798         > $DIR/$tfile || error "truncate failed"
12799         lctl set_param fail_loc=0
12800         echo "Truncate succeeded."
12801         rm -f $DIR/$tfile
12802 }
12803 run_test 117 "verify osd extend =========="
12804
12805 NO_SLOW_RESENDCOUNT=4
12806 export OLD_RESENDCOUNT=""
12807 set_resend_count () {
12808         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12809         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12810         lctl set_param -n $PROC_RESENDCOUNT $1
12811         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12812 }
12813
12814 # for reduce test_118* time (b=14842)
12815 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12816
12817 # Reset async IO behavior after error case
12818 reset_async() {
12819         FILE=$DIR/reset_async
12820
12821         # Ensure all OSCs are cleared
12822         $LFS setstripe -c -1 $FILE
12823         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12824         sync
12825         rm $FILE
12826 }
12827
12828 test_118a() #bug 11710
12829 {
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831
12832         reset_async
12833
12834         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12835         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12836         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12837
12838         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12839                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12840                 return 1;
12841         fi
12842         rm -f $DIR/$tfile
12843 }
12844 run_test 118a "verify O_SYNC works =========="
12845
12846 test_118b()
12847 {
12848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12849         remote_ost_nodsh && skip "remote OST with nodsh"
12850
12851         reset_async
12852
12853         #define OBD_FAIL_SRV_ENOENT 0x217
12854         set_nodes_failloc "$(osts_nodes)" 0x217
12855         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12856         RC=$?
12857         set_nodes_failloc "$(osts_nodes)" 0
12858         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12859         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12860                     grep -c writeback)
12861
12862         if [[ $RC -eq 0 ]]; then
12863                 error "Must return error due to dropped pages, rc=$RC"
12864                 return 1;
12865         fi
12866
12867         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12868                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12869                 return 1;
12870         fi
12871
12872         echo "Dirty pages not leaked on ENOENT"
12873
12874         # Due to the above error the OSC will issue all RPCs syncronously
12875         # until a subsequent RPC completes successfully without error.
12876         $MULTIOP $DIR/$tfile Ow4096yc
12877         rm -f $DIR/$tfile
12878
12879         return 0
12880 }
12881 run_test 118b "Reclaim dirty pages on fatal error =========="
12882
12883 test_118c()
12884 {
12885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12886
12887         # for 118c, restore the original resend count, LU-1940
12888         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12889                                 set_resend_count $OLD_RESENDCOUNT
12890         remote_ost_nodsh && skip "remote OST with nodsh"
12891
12892         reset_async
12893
12894         #define OBD_FAIL_OST_EROFS               0x216
12895         set_nodes_failloc "$(osts_nodes)" 0x216
12896
12897         # multiop should block due to fsync until pages are written
12898         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12899         MULTIPID=$!
12900         sleep 1
12901
12902         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12903                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12904         fi
12905
12906         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12907                     grep -c writeback)
12908         if [[ $WRITEBACK -eq 0 ]]; then
12909                 error "No page in writeback, writeback=$WRITEBACK"
12910         fi
12911
12912         set_nodes_failloc "$(osts_nodes)" 0
12913         wait $MULTIPID
12914         RC=$?
12915         if [[ $RC -ne 0 ]]; then
12916                 error "Multiop fsync failed, rc=$RC"
12917         fi
12918
12919         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12920         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12921                     grep -c writeback)
12922         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12923                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12924         fi
12925
12926         rm -f $DIR/$tfile
12927         echo "Dirty pages flushed via fsync on EROFS"
12928         return 0
12929 }
12930 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12931
12932 # continue to use small resend count to reduce test_118* time (b=14842)
12933 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12934
12935 test_118d()
12936 {
12937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12938         remote_ost_nodsh && skip "remote OST with nodsh"
12939
12940         reset_async
12941
12942         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12943         set_nodes_failloc "$(osts_nodes)" 0x214
12944         # multiop should block due to fsync until pages are written
12945         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12946         MULTIPID=$!
12947         sleep 1
12948
12949         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12950                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12951         fi
12952
12953         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12954                     grep -c writeback)
12955         if [[ $WRITEBACK -eq 0 ]]; then
12956                 error "No page in writeback, writeback=$WRITEBACK"
12957         fi
12958
12959         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12960         set_nodes_failloc "$(osts_nodes)" 0
12961
12962         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12963         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12964                     grep -c writeback)
12965         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12966                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12967         fi
12968
12969         rm -f $DIR/$tfile
12970         echo "Dirty pages gaurenteed flushed via fsync"
12971         return 0
12972 }
12973 run_test 118d "Fsync validation inject a delay of the bulk =========="
12974
12975 test_118f() {
12976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12977
12978         reset_async
12979
12980         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12981         lctl set_param fail_loc=0x8000040a
12982
12983         # Should simulate EINVAL error which is fatal
12984         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12985         RC=$?
12986         if [[ $RC -eq 0 ]]; then
12987                 error "Must return error due to dropped pages, rc=$RC"
12988         fi
12989
12990         lctl set_param fail_loc=0x0
12991
12992         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12993         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12994         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12995                     grep -c writeback)
12996         if [[ $LOCKED -ne 0 ]]; then
12997                 error "Locked pages remain in cache, locked=$LOCKED"
12998         fi
12999
13000         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13001                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13002         fi
13003
13004         rm -f $DIR/$tfile
13005         echo "No pages locked after fsync"
13006
13007         reset_async
13008         return 0
13009 }
13010 run_test 118f "Simulate unrecoverable OSC side error =========="
13011
13012 test_118g() {
13013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13014
13015         reset_async
13016
13017         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13018         lctl set_param fail_loc=0x406
13019
13020         # simulate local -ENOMEM
13021         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13022         RC=$?
13023
13024         lctl set_param fail_loc=0
13025         if [[ $RC -eq 0 ]]; then
13026                 error "Must return error due to dropped pages, rc=$RC"
13027         fi
13028
13029         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13030         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13031         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13032                         grep -c writeback)
13033         if [[ $LOCKED -ne 0 ]]; then
13034                 error "Locked pages remain in cache, locked=$LOCKED"
13035         fi
13036
13037         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13038                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13039         fi
13040
13041         rm -f $DIR/$tfile
13042         echo "No pages locked after fsync"
13043
13044         reset_async
13045         return 0
13046 }
13047 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13048
13049 test_118h() {
13050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13051         remote_ost_nodsh && skip "remote OST with nodsh"
13052
13053         reset_async
13054
13055         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13056         set_nodes_failloc "$(osts_nodes)" 0x20e
13057         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13058         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13059         RC=$?
13060
13061         set_nodes_failloc "$(osts_nodes)" 0
13062         if [[ $RC -eq 0 ]]; then
13063                 error "Must return error due to dropped pages, rc=$RC"
13064         fi
13065
13066         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13067         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13068         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13069                     grep -c writeback)
13070         if [[ $LOCKED -ne 0 ]]; then
13071                 error "Locked pages remain in cache, locked=$LOCKED"
13072         fi
13073
13074         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13075                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13076         fi
13077
13078         rm -f $DIR/$tfile
13079         echo "No pages locked after fsync"
13080
13081         return 0
13082 }
13083 run_test 118h "Verify timeout in handling recoverables errors  =========="
13084
13085 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13086
13087 test_118i() {
13088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13089         remote_ost_nodsh && skip "remote OST with nodsh"
13090
13091         reset_async
13092
13093         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13094         set_nodes_failloc "$(osts_nodes)" 0x20e
13095
13096         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13097         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13098         PID=$!
13099         sleep 5
13100         set_nodes_failloc "$(osts_nodes)" 0
13101
13102         wait $PID
13103         RC=$?
13104         if [[ $RC -ne 0 ]]; then
13105                 error "got error, but should be not, rc=$RC"
13106         fi
13107
13108         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13109         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13110         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13111         if [[ $LOCKED -ne 0 ]]; then
13112                 error "Locked pages remain in cache, locked=$LOCKED"
13113         fi
13114
13115         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13116                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13117         fi
13118
13119         rm -f $DIR/$tfile
13120         echo "No pages locked after fsync"
13121
13122         return 0
13123 }
13124 run_test 118i "Fix error before timeout in recoverable error  =========="
13125
13126 [ "$SLOW" = "no" ] && set_resend_count 4
13127
13128 test_118j() {
13129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13130         remote_ost_nodsh && skip "remote OST with nodsh"
13131
13132         reset_async
13133
13134         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13135         set_nodes_failloc "$(osts_nodes)" 0x220
13136
13137         # return -EIO from OST
13138         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13139         RC=$?
13140         set_nodes_failloc "$(osts_nodes)" 0x0
13141         if [[ $RC -eq 0 ]]; then
13142                 error "Must return error due to dropped pages, rc=$RC"
13143         fi
13144
13145         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13146         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13147         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13148         if [[ $LOCKED -ne 0 ]]; then
13149                 error "Locked pages remain in cache, locked=$LOCKED"
13150         fi
13151
13152         # in recoverable error on OST we want resend and stay until it finished
13153         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13154                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13155         fi
13156
13157         rm -f $DIR/$tfile
13158         echo "No pages locked after fsync"
13159
13160         return 0
13161 }
13162 run_test 118j "Simulate unrecoverable OST side error =========="
13163
13164 test_118k()
13165 {
13166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13167         remote_ost_nodsh && skip "remote OSTs with nodsh"
13168
13169         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13170         set_nodes_failloc "$(osts_nodes)" 0x20e
13171         test_mkdir $DIR/$tdir
13172
13173         for ((i=0;i<10;i++)); do
13174                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13175                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13176                 SLEEPPID=$!
13177                 sleep 0.500s
13178                 kill $SLEEPPID
13179                 wait $SLEEPPID
13180         done
13181
13182         set_nodes_failloc "$(osts_nodes)" 0
13183         rm -rf $DIR/$tdir
13184 }
13185 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13186
13187 test_118l() # LU-646
13188 {
13189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13190
13191         test_mkdir $DIR/$tdir
13192         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13193         rm -rf $DIR/$tdir
13194 }
13195 run_test 118l "fsync dir"
13196
13197 test_118m() # LU-3066
13198 {
13199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13200
13201         test_mkdir $DIR/$tdir
13202         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13203         rm -rf $DIR/$tdir
13204 }
13205 run_test 118m "fdatasync dir ========="
13206
13207 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13208
13209 test_118n()
13210 {
13211         local begin
13212         local end
13213
13214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13215         remote_ost_nodsh && skip "remote OSTs with nodsh"
13216
13217         # Sleep to avoid a cached response.
13218         #define OBD_STATFS_CACHE_SECONDS 1
13219         sleep 2
13220
13221         # Inject a 10 second delay in the OST_STATFS handler.
13222         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13223         set_nodes_failloc "$(osts_nodes)" 0x242
13224
13225         begin=$SECONDS
13226         stat --file-system $MOUNT > /dev/null
13227         end=$SECONDS
13228
13229         set_nodes_failloc "$(osts_nodes)" 0
13230
13231         if ((end - begin > 20)); then
13232             error "statfs took $((end - begin)) seconds, expected 10"
13233         fi
13234 }
13235 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13236
13237 test_119a() # bug 11737
13238 {
13239         BSIZE=$((512 * 1024))
13240         directio write $DIR/$tfile 0 1 $BSIZE
13241         # We ask to read two blocks, which is more than a file size.
13242         # directio will indicate an error when requested and actual
13243         # sizes aren't equeal (a normal situation in this case) and
13244         # print actual read amount.
13245         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13246         if [ "$NOB" != "$BSIZE" ]; then
13247                 error "read $NOB bytes instead of $BSIZE"
13248         fi
13249         rm -f $DIR/$tfile
13250 }
13251 run_test 119a "Short directIO read must return actual read amount"
13252
13253 test_119b() # bug 11737
13254 {
13255         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13256
13257         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13259         sync
13260         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13261                 error "direct read failed"
13262         rm -f $DIR/$tfile
13263 }
13264 run_test 119b "Sparse directIO read must return actual read amount"
13265
13266 test_119c() # bug 13099
13267 {
13268         BSIZE=1048576
13269         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13270         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13271         rm -f $DIR/$tfile
13272 }
13273 run_test 119c "Testing for direct read hitting hole"
13274
13275 test_119d() # bug 15950
13276 {
13277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13278
13279         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13280         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13281         BSIZE=1048576
13282         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13283         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13284         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13285         lctl set_param fail_loc=0x40d
13286         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13287         pid_dio=$!
13288         sleep 1
13289         cat $DIR/$tfile > /dev/null &
13290         lctl set_param fail_loc=0
13291         pid_reads=$!
13292         wait $pid_dio
13293         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13294         sleep 2
13295         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13296         error "the read rpcs have not completed in 2s"
13297         rm -f $DIR/$tfile
13298         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13299 }
13300 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13301
13302 test_120a() {
13303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13304         remote_mds_nodsh && skip "remote MDS with nodsh"
13305         test_mkdir -i0 -c1 $DIR/$tdir
13306         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13307                 skip_env "no early lock cancel on server"
13308
13309         lru_resize_disable mdc
13310         lru_resize_disable osc
13311         cancel_lru_locks mdc
13312         # asynchronous object destroy at MDT could cause bl ast to client
13313         cancel_lru_locks osc
13314
13315         stat $DIR/$tdir > /dev/null
13316         can1=$(do_facet mds1 \
13317                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13318                awk '/ldlm_cancel/ {print $2}')
13319         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13320                awk '/ldlm_bl_callback/ {print $2}')
13321         test_mkdir -i0 -c1 $DIR/$tdir/d1
13322         can2=$(do_facet mds1 \
13323                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13324                awk '/ldlm_cancel/ {print $2}')
13325         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13326                awk '/ldlm_bl_callback/ {print $2}')
13327         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13328         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13329         lru_resize_enable mdc
13330         lru_resize_enable osc
13331 }
13332 run_test 120a "Early Lock Cancel: mkdir test"
13333
13334 test_120b() {
13335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13336         remote_mds_nodsh && skip "remote MDS with nodsh"
13337         test_mkdir $DIR/$tdir
13338         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13339                 skip_env "no early lock cancel on server"
13340
13341         lru_resize_disable mdc
13342         lru_resize_disable osc
13343         cancel_lru_locks mdc
13344         stat $DIR/$tdir > /dev/null
13345         can1=$(do_facet $SINGLEMDS \
13346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13347                awk '/ldlm_cancel/ {print $2}')
13348         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13349                awk '/ldlm_bl_callback/ {print $2}')
13350         touch $DIR/$tdir/f1
13351         can2=$(do_facet $SINGLEMDS \
13352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13353                awk '/ldlm_cancel/ {print $2}')
13354         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13355                awk '/ldlm_bl_callback/ {print $2}')
13356         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13357         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13358         lru_resize_enable mdc
13359         lru_resize_enable osc
13360 }
13361 run_test 120b "Early Lock Cancel: create test"
13362
13363 test_120c() {
13364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13365         remote_mds_nodsh && skip "remote MDS with nodsh"
13366         test_mkdir -i0 -c1 $DIR/$tdir
13367         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13368                 skip "no early lock cancel on server"
13369
13370         lru_resize_disable mdc
13371         lru_resize_disable osc
13372         test_mkdir -i0 -c1 $DIR/$tdir/d1
13373         test_mkdir -i0 -c1 $DIR/$tdir/d2
13374         touch $DIR/$tdir/d1/f1
13375         cancel_lru_locks mdc
13376         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13377         can1=$(do_facet mds1 \
13378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13379                awk '/ldlm_cancel/ {print $2}')
13380         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13381                awk '/ldlm_bl_callback/ {print $2}')
13382         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13383         can2=$(do_facet mds1 \
13384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13385                awk '/ldlm_cancel/ {print $2}')
13386         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13387                awk '/ldlm_bl_callback/ {print $2}')
13388         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13389         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13390         lru_resize_enable mdc
13391         lru_resize_enable osc
13392 }
13393 run_test 120c "Early Lock Cancel: link test"
13394
13395 test_120d() {
13396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13397         remote_mds_nodsh && skip "remote MDS with nodsh"
13398         test_mkdir -i0 -c1 $DIR/$tdir
13399         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13400                 skip_env "no early lock cancel on server"
13401
13402         lru_resize_disable mdc
13403         lru_resize_disable osc
13404         touch $DIR/$tdir
13405         cancel_lru_locks mdc
13406         stat $DIR/$tdir > /dev/null
13407         can1=$(do_facet mds1 \
13408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13409                awk '/ldlm_cancel/ {print $2}')
13410         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13411                awk '/ldlm_bl_callback/ {print $2}')
13412         chmod a+x $DIR/$tdir
13413         can2=$(do_facet mds1 \
13414                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13415                awk '/ldlm_cancel/ {print $2}')
13416         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13417                awk '/ldlm_bl_callback/ {print $2}')
13418         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13419         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13420         lru_resize_enable mdc
13421         lru_resize_enable osc
13422 }
13423 run_test 120d "Early Lock Cancel: setattr test"
13424
13425 test_120e() {
13426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13427         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13428                 skip_env "no early lock cancel on server"
13429         remote_mds_nodsh && skip "remote MDS with nodsh"
13430
13431         local dlmtrace_set=false
13432
13433         test_mkdir -i0 -c1 $DIR/$tdir
13434         lru_resize_disable mdc
13435         lru_resize_disable osc
13436         ! $LCTL get_param debug | grep -q dlmtrace &&
13437                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13438         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13439         cancel_lru_locks mdc
13440         cancel_lru_locks osc
13441         dd if=$DIR/$tdir/f1 of=/dev/null
13442         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13443         # XXX client can not do early lock cancel of OST lock
13444         # during unlink (LU-4206), so cancel osc lock now.
13445         sleep 2
13446         cancel_lru_locks osc
13447         can1=$(do_facet mds1 \
13448                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13449                awk '/ldlm_cancel/ {print $2}')
13450         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13451                awk '/ldlm_bl_callback/ {print $2}')
13452         unlink $DIR/$tdir/f1
13453         sleep 5
13454         can2=$(do_facet mds1 \
13455                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13456                awk '/ldlm_cancel/ {print $2}')
13457         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13458                awk '/ldlm_bl_callback/ {print $2}')
13459         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13460                 $LCTL dk $TMP/cancel.debug.txt
13461         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13462                 $LCTL dk $TMP/blocking.debug.txt
13463         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13464         lru_resize_enable mdc
13465         lru_resize_enable osc
13466 }
13467 run_test 120e "Early Lock Cancel: unlink test"
13468
13469 test_120f() {
13470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13471         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13472                 skip_env "no early lock cancel on server"
13473         remote_mds_nodsh && skip "remote MDS with nodsh"
13474
13475         test_mkdir -i0 -c1 $DIR/$tdir
13476         lru_resize_disable mdc
13477         lru_resize_disable osc
13478         test_mkdir -i0 -c1 $DIR/$tdir/d1
13479         test_mkdir -i0 -c1 $DIR/$tdir/d2
13480         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13481         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13482         cancel_lru_locks mdc
13483         cancel_lru_locks osc
13484         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13485         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13486         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13487         # XXX client can not do early lock cancel of OST lock
13488         # during rename (LU-4206), so cancel osc lock now.
13489         sleep 2
13490         cancel_lru_locks osc
13491         can1=$(do_facet mds1 \
13492                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13493                awk '/ldlm_cancel/ {print $2}')
13494         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13495                awk '/ldlm_bl_callback/ {print $2}')
13496         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13497         sleep 5
13498         can2=$(do_facet mds1 \
13499                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13500                awk '/ldlm_cancel/ {print $2}')
13501         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13502                awk '/ldlm_bl_callback/ {print $2}')
13503         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13504         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13505         lru_resize_enable mdc
13506         lru_resize_enable osc
13507 }
13508 run_test 120f "Early Lock Cancel: rename test"
13509
13510 test_120g() {
13511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13512         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13513                 skip_env "no early lock cancel on server"
13514         remote_mds_nodsh && skip "remote MDS with nodsh"
13515
13516         lru_resize_disable mdc
13517         lru_resize_disable osc
13518         count=10000
13519         echo create $count files
13520         test_mkdir $DIR/$tdir
13521         cancel_lru_locks mdc
13522         cancel_lru_locks osc
13523         t0=$(date +%s)
13524
13525         can0=$(do_facet $SINGLEMDS \
13526                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13527                awk '/ldlm_cancel/ {print $2}')
13528         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13529                awk '/ldlm_bl_callback/ {print $2}')
13530         createmany -o $DIR/$tdir/f $count
13531         sync
13532         can1=$(do_facet $SINGLEMDS \
13533                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13534                awk '/ldlm_cancel/ {print $2}')
13535         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13536                awk '/ldlm_bl_callback/ {print $2}')
13537         t1=$(date +%s)
13538         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13539         echo rm $count files
13540         rm -r $DIR/$tdir
13541         sync
13542         can2=$(do_facet $SINGLEMDS \
13543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13544                awk '/ldlm_cancel/ {print $2}')
13545         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13546                awk '/ldlm_bl_callback/ {print $2}')
13547         t2=$(date +%s)
13548         echo total: $count removes in $((t2-t1))
13549         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13550         sleep 2
13551         # wait for commitment of removal
13552         lru_resize_enable mdc
13553         lru_resize_enable osc
13554 }
13555 run_test 120g "Early Lock Cancel: performance test"
13556
13557 test_121() { #bug #10589
13558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13559
13560         rm -rf $DIR/$tfile
13561         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13562 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13563         lctl set_param fail_loc=0x310
13564         cancel_lru_locks osc > /dev/null
13565         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13566         lctl set_param fail_loc=0
13567         [[ $reads -eq $writes ]] ||
13568                 error "read $reads blocks, must be $writes blocks"
13569 }
13570 run_test 121 "read cancel race ========="
13571
13572 test_123a_base() { # was test 123, statahead(bug 11401)
13573         local lsx="$1"
13574
13575         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13576
13577         SLOWOK=0
13578         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13579                 log "testing UP system. Performance may be lower than expected."
13580                 SLOWOK=1
13581         fi
13582         running_in_vm && SLOWOK=1
13583
13584         $LCTL set_param mdc.*.batch_stats=0
13585
13586         rm -rf $DIR/$tdir
13587         test_mkdir $DIR/$tdir
13588         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13589         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13590         MULT=10
13591         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13592                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13593
13594                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13595                 lctl set_param -n llite.*.statahead_max 0
13596                 lctl get_param llite.*.statahead_max
13597                 cancel_lru_locks mdc
13598                 cancel_lru_locks osc
13599                 stime=$(date +%s)
13600                 time $lsx $DIR/$tdir | wc -l
13601                 etime=$(date +%s)
13602                 delta=$((etime - stime))
13603                 log "$lsx $i files without statahead: $delta sec"
13604                 lctl set_param llite.*.statahead_max=$max
13605
13606                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13607                          awk '/statahead.wrong:/ { print $NF }')
13608                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13609                 cancel_lru_locks mdc
13610                 cancel_lru_locks osc
13611                 stime=$(date +%s)
13612                 time $lsx $DIR/$tdir | wc -l
13613                 etime=$(date +%s)
13614                 delta_sa=$((etime - stime))
13615                 log "$lsx $i files with statahead: $delta_sa sec"
13616                 lctl get_param -n llite.*.statahead_stats
13617                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13618                          awk '/statahead.wrong:/ { print $NF }')
13619
13620                 [[ $swrong -lt $ewrong ]] &&
13621                         log "statahead was stopped, maybe too many locks held!"
13622                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13623
13624                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13625                         max=$(lctl get_param -n llite.*.statahead_max |
13626                                 head -n 1)
13627                         lctl set_param -n llite.*.statahead_max 0
13628                         lctl get_param llite.*.statahead_max
13629                         cancel_lru_locks mdc
13630                         cancel_lru_locks osc
13631                         stime=$(date +%s)
13632                         time $lsx $DIR/$tdir | wc -l
13633                         etime=$(date +%s)
13634                         delta=$((etime - stime))
13635                         log "$lsx $i files again without statahead: $delta sec"
13636                         lctl set_param llite.*.statahead_max=$max
13637                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13638                                 if [ $SLOWOK -eq 0 ]; then
13639                                         error "$lsx $i files is slower with statahead!"
13640                                 else
13641                                         log "$lsx $i files is slower with statahead!"
13642                                 fi
13643                                 break
13644                         fi
13645                 fi
13646
13647                 [ $delta -gt 20 ] && break
13648                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13649                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13650         done
13651         log "$lsx done"
13652
13653         stime=$(date +%s)
13654         rm -r $DIR/$tdir
13655         sync
13656         etime=$(date +%s)
13657         delta=$((etime - stime))
13658         log "rm -r $DIR/$tdir/: $delta seconds"
13659         log "rm done"
13660         lctl get_param -n llite.*.statahead_stats
13661         $LCTL get_param mdc.*.batch_stats
13662 }
13663
13664 test_123aa() {
13665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13666
13667         test_123a_base "ls -l"
13668 }
13669 run_test 123aa "verify statahead work"
13670
13671 test_123ab() {
13672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13673
13674         statx_supported || skip_env "Test must be statx() syscall supported"
13675
13676         test_123a_base "$STATX -l"
13677 }
13678 run_test 123ab "verify statahead work by using statx"
13679
13680 test_123ac() {
13681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13682
13683         statx_supported || skip_env "Test must be statx() syscall supported"
13684
13685         local rpcs_before
13686         local rpcs_after
13687         local agl_before
13688         local agl_after
13689
13690         cancel_lru_locks $OSC
13691         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13692         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13693                      awk '/agl.total:/ { print $NF }')
13694         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13695         test_123a_base "$STATX --cached=always -D"
13696         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13697                     awk '/agl.total:/ { print $NF }')
13698         [ $agl_before -eq $agl_after ] ||
13699                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13700         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13701         [ $rpcs_after -eq $rpcs_before ] ||
13702                 error "$STATX should not send glimpse RPCs to $OSC"
13703 }
13704 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13705
13706 test_123b () { # statahead(bug 15027)
13707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13708
13709         test_mkdir $DIR/$tdir
13710         createmany -o $DIR/$tdir/$tfile-%d 1000
13711
13712         cancel_lru_locks mdc
13713         cancel_lru_locks osc
13714
13715 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13716         lctl set_param fail_loc=0x80000803
13717         ls -lR $DIR/$tdir > /dev/null
13718         log "ls done"
13719         lctl set_param fail_loc=0x0
13720         lctl get_param -n llite.*.statahead_stats
13721         rm -r $DIR/$tdir
13722         sync
13723
13724 }
13725 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13726
13727 test_123c() {
13728         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13729
13730         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13731         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13732         touch $DIR/$tdir.1/{1..3}
13733         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13734
13735         remount_client $MOUNT
13736
13737         $MULTIOP $DIR/$tdir.0 Q
13738
13739         # let statahead to complete
13740         ls -l $DIR/$tdir.0 > /dev/null
13741
13742         testid=$(echo $TESTNAME | tr '_' ' ')
13743         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13744                 error "statahead warning" || true
13745 }
13746 run_test 123c "Can not initialize inode warning on DNE statahead"
13747
13748 test_123d() {
13749         local num=100
13750         local swrong
13751         local ewrong
13752
13753         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13754         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13755                 error "setdirstripe $DIR/$tdir failed"
13756         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13757         remount_client $MOUNT
13758         $LCTL get_param llite.*.statahead_max
13759         $LCTL set_param llite.*.statahead_stats=0 ||
13760                 error "clear statahead_stats failed"
13761         swrong=$(lctl get_param -n llite.*.statahead_stats |
13762                  awk '/statahead.wrong:/ { print $NF }')
13763         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13764         # wait for statahead thread finished to update hit/miss stats.
13765         sleep 1
13766         $LCTL get_param -n llite.*.statahead_stats
13767         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13768                  awk '/statahead.wrong:/ { print $NF }')
13769         (( $swrong == $ewrong )) ||
13770                 log "statahead was stopped, maybe too many locks held!"
13771 }
13772 run_test 123d "Statahead on striped directories works correctly"
13773
13774 test_123e() {
13775         local max
13776         local batch_max
13777         local dir=$DIR/$tdir
13778
13779         mkdir $dir || error "mkdir $dir failed"
13780         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13781
13782         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13783
13784         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13785         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13786         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13787         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13788
13789         $LCTL set_param llite.*.statahead_max=2048
13790         $LCTL set_param llite.*.statahead_batch_max=1024
13791
13792         ls -l $dir
13793         $LCTL get_param mdc.*.batch_stats
13794         $LCTL get_param llite.*.statahead_*
13795 }
13796 run_test 123e "statahead with large wide striping"
13797
13798 test_124a() {
13799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13800         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13801                 skip_env "no lru resize on server"
13802
13803         local NR=2000
13804
13805         test_mkdir $DIR/$tdir
13806
13807         log "create $NR files at $DIR/$tdir"
13808         createmany -o $DIR/$tdir/f $NR ||
13809                 error "failed to create $NR files in $DIR/$tdir"
13810
13811         cancel_lru_locks mdc
13812         ls -l $DIR/$tdir > /dev/null
13813
13814         local NSDIR=""
13815         local LRU_SIZE=0
13816         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13817                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13818                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13819                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13820                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13821                         log "NSDIR=$NSDIR"
13822                         log "NS=$(basename $NSDIR)"
13823                         break
13824                 fi
13825         done
13826
13827         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13828                 skip "Not enough cached locks created!"
13829         fi
13830         log "LRU=$LRU_SIZE"
13831
13832         local SLEEP=30
13833
13834         # We know that lru resize allows one client to hold $LIMIT locks
13835         # for 10h. After that locks begin to be killed by client.
13836         local MAX_HRS=10
13837         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13838         log "LIMIT=$LIMIT"
13839         if [ $LIMIT -lt $LRU_SIZE ]; then
13840                 skip "Limit is too small $LIMIT"
13841         fi
13842
13843         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13844         # killing locks. Some time was spent for creating locks. This means
13845         # that up to the moment of sleep finish we must have killed some of
13846         # them (10-100 locks). This depends on how fast ther were created.
13847         # Many of them were touched in almost the same moment and thus will
13848         # be killed in groups.
13849         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13850
13851         # Use $LRU_SIZE_B here to take into account real number of locks
13852         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13853         local LRU_SIZE_B=$LRU_SIZE
13854         log "LVF=$LVF"
13855         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13856         log "OLD_LVF=$OLD_LVF"
13857         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13858
13859         # Let's make sure that we really have some margin. Client checks
13860         # cached locks every 10 sec.
13861         SLEEP=$((SLEEP+20))
13862         log "Sleep ${SLEEP} sec"
13863         local SEC=0
13864         while ((SEC<$SLEEP)); do
13865                 echo -n "..."
13866                 sleep 5
13867                 SEC=$((SEC+5))
13868                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13869                 echo -n "$LRU_SIZE"
13870         done
13871         echo ""
13872         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13873         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13874
13875         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13876                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13877                 unlinkmany $DIR/$tdir/f $NR
13878                 return
13879         }
13880
13881         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13882         log "unlink $NR files at $DIR/$tdir"
13883         unlinkmany $DIR/$tdir/f $NR
13884 }
13885 run_test 124a "lru resize ======================================="
13886
13887 get_max_pool_limit()
13888 {
13889         local limit=$($LCTL get_param \
13890                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13891         local max=0
13892         for l in $limit; do
13893                 if [[ $l -gt $max ]]; then
13894                         max=$l
13895                 fi
13896         done
13897         echo $max
13898 }
13899
13900 test_124b() {
13901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13902         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13903                 skip_env "no lru resize on server"
13904
13905         LIMIT=$(get_max_pool_limit)
13906
13907         NR=$(($(default_lru_size)*20))
13908         if [[ $NR -gt $LIMIT ]]; then
13909                 log "Limit lock number by $LIMIT locks"
13910                 NR=$LIMIT
13911         fi
13912
13913         IFree=$(mdsrate_inodes_available)
13914         if [ $IFree -lt $NR ]; then
13915                 log "Limit lock number by $IFree inodes"
13916                 NR=$IFree
13917         fi
13918
13919         lru_resize_disable mdc
13920         test_mkdir -p $DIR/$tdir/disable_lru_resize
13921
13922         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13923         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13924         cancel_lru_locks mdc
13925         stime=`date +%s`
13926         PID=""
13927         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13928         PID="$PID $!"
13929         sleep 2
13930         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13931         PID="$PID $!"
13932         sleep 2
13933         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13934         PID="$PID $!"
13935         wait $PID
13936         etime=`date +%s`
13937         nolruresize_delta=$((etime-stime))
13938         log "ls -la time: $nolruresize_delta seconds"
13939         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13940         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13941
13942         lru_resize_enable mdc
13943         test_mkdir -p $DIR/$tdir/enable_lru_resize
13944
13945         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13946         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13947         cancel_lru_locks mdc
13948         stime=`date +%s`
13949         PID=""
13950         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13951         PID="$PID $!"
13952         sleep 2
13953         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13954         PID="$PID $!"
13955         sleep 2
13956         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13957         PID="$PID $!"
13958         wait $PID
13959         etime=`date +%s`
13960         lruresize_delta=$((etime-stime))
13961         log "ls -la time: $lruresize_delta seconds"
13962         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13963
13964         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13965                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13966         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13967                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13968         else
13969                 log "lru resize performs the same with no lru resize"
13970         fi
13971         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13972 }
13973 run_test 124b "lru resize (performance test) ======================="
13974
13975 test_124c() {
13976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13977         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13978                 skip_env "no lru resize on server"
13979
13980         # cache ununsed locks on client
13981         local nr=100
13982         cancel_lru_locks mdc
13983         test_mkdir $DIR/$tdir
13984         createmany -o $DIR/$tdir/f $nr ||
13985                 error "failed to create $nr files in $DIR/$tdir"
13986         ls -l $DIR/$tdir > /dev/null
13987
13988         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13989         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13990         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13991         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13992         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13993
13994         # set lru_max_age to 1 sec
13995         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13996         echo "sleep $((recalc_p * 2)) seconds..."
13997         sleep $((recalc_p * 2))
13998
13999         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14000         # restore lru_max_age
14001         $LCTL set_param -n $nsdir.lru_max_age $max_age
14002         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14003         unlinkmany $DIR/$tdir/f $nr
14004 }
14005 run_test 124c "LRUR cancel very aged locks"
14006
14007 test_124d() {
14008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14009         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14010                 skip_env "no lru resize on server"
14011
14012         # cache ununsed locks on client
14013         local nr=100
14014
14015         lru_resize_disable mdc
14016         stack_trap "lru_resize_enable mdc" EXIT
14017
14018         cancel_lru_locks mdc
14019
14020         # asynchronous object destroy at MDT could cause bl ast to client
14021         test_mkdir $DIR/$tdir
14022         createmany -o $DIR/$tdir/f $nr ||
14023                 error "failed to create $nr files in $DIR/$tdir"
14024         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14025
14026         ls -l $DIR/$tdir > /dev/null
14027
14028         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14029         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14030         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14031         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14032
14033         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14034
14035         # set lru_max_age to 1 sec
14036         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14037         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14038
14039         echo "sleep $((recalc_p * 2)) seconds..."
14040         sleep $((recalc_p * 2))
14041
14042         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14043
14044         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14045 }
14046 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14047
14048 test_125() { # 13358
14049         $LCTL get_param -n llite.*.client_type | grep -q local ||
14050                 skip "must run as local client"
14051         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14052                 skip_env "must have acl enabled"
14053         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14054
14055         test_mkdir $DIR/$tdir
14056         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14057         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14058                 error "setfacl $DIR/$tdir failed"
14059         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14060 }
14061 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14062
14063 test_126() { # bug 12829/13455
14064         $GSS && skip_env "must run as gss disabled"
14065         $LCTL get_param -n llite.*.client_type | grep -q local ||
14066                 skip "must run as local client"
14067         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14068
14069         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14070         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14071         rm -f $DIR/$tfile
14072         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14073 }
14074 run_test 126 "check that the fsgid provided by the client is taken into account"
14075
14076 test_127a() { # bug 15521
14077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14078         local name count samp unit min max sum sumsq
14079         local tmpfile=$TMP/$tfile.tmp
14080
14081         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14082         echo "stats before reset"
14083         stack_trap "rm -f $tmpfile"
14084         local now=$(date +%s)
14085
14086         $LCTL get_param osc.*.stats | tee $tmpfile
14087
14088         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14089         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14090         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14091         local uptime=$(awk '{ print $1 }' /proc/uptime)
14092
14093         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14094         (( ${snapshot_time%\.*} >= $now - 5 &&
14095            ${snapshot_time%\.*} <= $now + 5 )) ||
14096                 error "snapshot_time=$snapshot_time != now=$now"
14097         # elapsed _should_ be from mount, but at least less than uptime
14098         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14099                 error "elapsed=$elapsed > uptime=$uptime"
14100         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14101            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14102                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14103
14104         $LCTL set_param osc.*.stats=0
14105         local reset=$(date +%s)
14106         local fsize=$((2048 * 1024))
14107
14108         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14109         cancel_lru_locks osc
14110         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14111
14112         now=$(date +%s)
14113         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14114         while read name count samp unit min max sum sumsq; do
14115                 [[ "$samp" == "samples" ]] || continue
14116
14117                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14118                 [ ! $min ] && error "Missing min value for $name proc entry"
14119                 eval $name=$count || error "Wrong proc format"
14120
14121                 case $name in
14122                 read_bytes|write_bytes)
14123                         [[ "$unit" =~ "bytes" ]] ||
14124                                 error "unit is not 'bytes': $unit"
14125                         (( $min >= 4096 )) || error "min is too small: $min"
14126                         (( $min <= $fsize )) || error "min is too big: $min"
14127                         (( $max >= 4096 )) || error "max is too small: $max"
14128                         (( $max <= $fsize )) || error "max is too big: $max"
14129                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14130                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14131                                 error "sumsquare is too small: $sumsq"
14132                         (( $sumsq <= $fsize * $fsize )) ||
14133                                 error "sumsquare is too big: $sumsq"
14134                         ;;
14135                 ost_read|ost_write)
14136                         [[ "$unit" =~ "usec" ]] ||
14137                                 error "unit is not 'usec': $unit"
14138                         ;;
14139                 *)      ;;
14140                 esac
14141         done < $tmpfile
14142
14143         #check that we actually got some stats
14144         [ "$read_bytes" ] || error "Missing read_bytes stats"
14145         [ "$write_bytes" ] || error "Missing write_bytes stats"
14146         [ "$read_bytes" != 0 ] || error "no read done"
14147         [ "$write_bytes" != 0 ] || error "no write done"
14148
14149         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14150         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14151         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14152
14153         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14154         (( ${snapshot_time%\.*} >= $now - 5 &&
14155            ${snapshot_time%\.*} <= $now + 5 )) ||
14156                 error "reset snapshot_time=$snapshot_time != now=$now"
14157         # elapsed should be from time of stats reset
14158         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14159            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14160                 error "reset elapsed=$elapsed > $now - $reset"
14161         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14162            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14163                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14164 }
14165 run_test 127a "verify the client stats are sane"
14166
14167 test_127b() { # bug LU-333
14168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14169         local name count samp unit min max sum sumsq
14170
14171         echo "stats before reset"
14172         $LCTL get_param llite.*.stats
14173         $LCTL set_param llite.*.stats=0
14174
14175         # perform 2 reads and writes so MAX is different from SUM.
14176         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14177         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14178         cancel_lru_locks osc
14179         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14180         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14181
14182         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14183         stack_trap "rm -f $TMP/$tfile.tmp"
14184         while read name count samp unit min max sum sumsq; do
14185                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14186                 eval $name=$count || error "Wrong proc format"
14187
14188                 case $name in
14189                 read_bytes|write_bytes)
14190                         [[ "$unit" =~ "bytes" ]] ||
14191                                 error "unit is not 'bytes': $unit"
14192                         (( $count == 2 )) || error "count is not 2: $count"
14193                         (( $min == $PAGE_SIZE )) ||
14194                                 error "min is not $PAGE_SIZE: $min"
14195                         (( $max == $PAGE_SIZE )) ||
14196                                 error "max is not $PAGE_SIZE: $max"
14197                         (( $sum == $PAGE_SIZE * 2 )) ||
14198                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14199                         ;;
14200                 read|write)
14201                         [[ "$unit" =~ "usec" ]] ||
14202                                 error "unit is not 'usec': $unit"
14203                         ;;
14204                 *)      ;;
14205                 esac
14206         done < $TMP/$tfile.tmp
14207
14208         #check that we actually got some stats
14209         [ "$read_bytes" ] || error "Missing read_bytes stats"
14210         [ "$write_bytes" ] || error "Missing write_bytes stats"
14211         [ "$read_bytes" != 0 ] || error "no read done"
14212         [ "$write_bytes" != 0 ] || error "no write done"
14213 }
14214 run_test 127b "verify the llite client stats are sane"
14215
14216 test_127c() { # LU-12394
14217         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14218         local size
14219         local bsize
14220         local reads
14221         local writes
14222         local count
14223
14224         $LCTL set_param llite.*.extents_stats=1
14225         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14226
14227         # Use two stripes so there is enough space in default config
14228         $LFS setstripe -c 2 $DIR/$tfile
14229
14230         # Extent stats start at 0-4K and go in power of two buckets
14231         # LL_HIST_START = 12 --> 2^12 = 4K
14232         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14233         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14234         # small configs
14235         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14236                 do
14237                 # Write and read, 2x each, second time at a non-zero offset
14238                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14239                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14240                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14241                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14242                 rm -f $DIR/$tfile
14243         done
14244
14245         $LCTL get_param llite.*.extents_stats
14246
14247         count=2
14248         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14249                 do
14250                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14251                                 grep -m 1 $bsize)
14252                 reads=$(echo $bucket | awk '{print $5}')
14253                 writes=$(echo $bucket | awk '{print $9}')
14254                 [ "$reads" -eq $count ] ||
14255                         error "$reads reads in < $bsize bucket, expect $count"
14256                 [ "$writes" -eq $count ] ||
14257                         error "$writes writes in < $bsize bucket, expect $count"
14258         done
14259
14260         # Test mmap write and read
14261         $LCTL set_param llite.*.extents_stats=c
14262         size=512
14263         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14264         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14265         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14266
14267         $LCTL get_param llite.*.extents_stats
14268
14269         count=$(((size*1024) / PAGE_SIZE))
14270
14271         bsize=$((2 * PAGE_SIZE / 1024))K
14272
14273         bucket=$($LCTL get_param -n llite.*.extents_stats |
14274                         grep -m 1 $bsize)
14275         reads=$(echo $bucket | awk '{print $5}')
14276         writes=$(echo $bucket | awk '{print $9}')
14277         # mmap writes fault in the page first, creating an additonal read
14278         [ "$reads" -eq $((2 * count)) ] ||
14279                 error "$reads reads in < $bsize bucket, expect $count"
14280         [ "$writes" -eq $count ] ||
14281                 error "$writes writes in < $bsize bucket, expect $count"
14282 }
14283 run_test 127c "test llite extent stats with regular & mmap i/o"
14284
14285 test_128() { # bug 15212
14286         touch $DIR/$tfile
14287         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14288                 find $DIR/$tfile
14289                 find $DIR/$tfile
14290         EOF
14291
14292         result=$(grep error $TMP/$tfile.log)
14293         rm -f $DIR/$tfile $TMP/$tfile.log
14294         [ -z "$result" ] ||
14295                 error "consecutive find's under interactive lfs failed"
14296 }
14297 run_test 128 "interactive lfs for 2 consecutive find's"
14298
14299 set_dir_limits () {
14300         local mntdev
14301         local canondev
14302         local node
14303
14304         local ldproc=/proc/fs/ldiskfs
14305         local facets=$(get_facets MDS)
14306
14307         for facet in ${facets//,/ }; do
14308                 canondev=$(ldiskfs_canon \
14309                            *.$(convert_facet2label $facet).mntdev $facet)
14310                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14311                         ldproc=/sys/fs/ldiskfs
14312                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14313                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14314         done
14315 }
14316
14317 check_mds_dmesg() {
14318         local facets=$(get_facets MDS)
14319         for facet in ${facets//,/ }; do
14320                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14321         done
14322         return 1
14323 }
14324
14325 test_129() {
14326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14327         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14328                 skip "Need MDS version with at least 2.5.56"
14329         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14330                 skip_env "ldiskfs only test"
14331         fi
14332         remote_mds_nodsh && skip "remote MDS with nodsh"
14333
14334         local ENOSPC=28
14335         local has_warning=false
14336
14337         rm -rf $DIR/$tdir
14338         mkdir -p $DIR/$tdir
14339
14340         # block size of mds1
14341         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14342         set_dir_limits $maxsize $((maxsize * 6 / 8))
14343         stack_trap "set_dir_limits 0 0"
14344         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14345         local dirsize=$(stat -c%s "$DIR/$tdir")
14346         local nfiles=0
14347         while (( $dirsize <= $maxsize )); do
14348                 $MCREATE $DIR/$tdir/file_base_$nfiles
14349                 rc=$?
14350                 # check two errors:
14351                 # ENOSPC for ext4 max_dir_size, which has been used since
14352                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14353                 if (( rc == ENOSPC )); then
14354                         set_dir_limits 0 0
14355                         echo "rc=$rc returned as expected after $nfiles files"
14356
14357                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14358                                 error "create failed w/o dir size limit"
14359
14360                         # messages may be rate limited if test is run repeatedly
14361                         check_mds_dmesg '"is approaching max"' ||
14362                                 echo "warning message should be output"
14363                         check_mds_dmesg '"has reached max"' ||
14364                                 echo "reached message should be output"
14365
14366                         dirsize=$(stat -c%s "$DIR/$tdir")
14367
14368                         [[ $dirsize -ge $maxsize ]] && return 0
14369                         error "dirsize $dirsize < $maxsize after $nfiles files"
14370                 elif (( rc != 0 )); then
14371                         break
14372                 fi
14373                 nfiles=$((nfiles + 1))
14374                 dirsize=$(stat -c%s "$DIR/$tdir")
14375         done
14376
14377         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14378 }
14379 run_test 129 "test directory size limit ========================"
14380
14381 OLDIFS="$IFS"
14382 cleanup_130() {
14383         trap 0
14384         IFS="$OLDIFS"
14385 }
14386
14387 test_130a() {
14388         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14389         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14390
14391         trap cleanup_130 EXIT RETURN
14392
14393         local fm_file=$DIR/$tfile
14394         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14395         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14396                 error "dd failed for $fm_file"
14397
14398         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14399         filefrag -ves $fm_file
14400         local rc=$?
14401         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14402                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14403         (( $rc == 0 )) || error "filefrag $fm_file failed"
14404
14405         filefrag_op=$(filefrag -ve -k $fm_file |
14406                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14407         local lun=$($LFS getstripe -i $fm_file)
14408
14409         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14410         IFS=$'\n'
14411         local tot_len=0
14412         for line in $filefrag_op; do
14413                 local frag_lun=$(echo $line | cut -d: -f5)
14414                 local ext_len=$(echo $line | cut -d: -f4)
14415
14416                 if (( $frag_lun != $lun )); then
14417                         error "FIEMAP on 1-stripe file($fm_file) failed"
14418                         return
14419                 fi
14420                 (( tot_len += ext_len ))
14421         done
14422
14423         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14424                 error "FIEMAP on 1-stripe file($fm_file) failed"
14425                 return
14426         fi
14427
14428         echo "FIEMAP on single striped file succeeded"
14429 }
14430 run_test 130a "FIEMAP (1-stripe file)"
14431
14432 test_130b() {
14433         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14434
14435         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14436         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14437         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14438                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14439
14440         trap cleanup_130 EXIT RETURN
14441
14442         local fm_file=$DIR/$tfile
14443         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14444                 error "setstripe on $fm_file"
14445
14446         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14447                 error "dd failed on $fm_file"
14448
14449         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14450         filefrag_op=$(filefrag -ve -k $fm_file |
14451                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14452
14453         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14454                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14455
14456         IFS=$'\n'
14457         local tot_len=0
14458         local num_luns=1
14459
14460         for line in $filefrag_op; do
14461                 local frag_lun=$(echo $line | cut -d: -f5 |
14462                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14463                 local ext_len=$(echo $line | cut -d: -f4)
14464                 if (( $frag_lun != $last_lun )); then
14465                         if (( tot_len != 1024 )); then
14466                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14467                                 return
14468                         else
14469                                 (( num_luns += 1 ))
14470                                 tot_len=0
14471                         fi
14472                 fi
14473                 (( tot_len += ext_len ))
14474                 last_lun=$frag_lun
14475         done
14476         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14477                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14478                 return
14479         fi
14480
14481         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14482 }
14483 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14484
14485 test_130c() {
14486         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14487
14488         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14489         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14490         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14491                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14492
14493         trap cleanup_130 EXIT RETURN
14494
14495         local fm_file=$DIR/$tfile
14496         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14497
14498         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14499                 error "dd failed on $fm_file"
14500
14501         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14502         filefrag_op=$(filefrag -ve -k $fm_file |
14503                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14504
14505         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14506                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14507
14508         IFS=$'\n'
14509         local tot_len=0
14510         local num_luns=1
14511         for line in $filefrag_op; do
14512                 local frag_lun=$(echo $line | cut -d: -f5 |
14513                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14514                 local ext_len=$(echo $line | cut -d: -f4)
14515                 if (( $frag_lun != $last_lun )); then
14516                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14517                         if (( logical != 512 )); then
14518                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14519                                 return
14520                         fi
14521                         if (( tot_len != 512 )); then
14522                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14523                                 return
14524                         else
14525                                 (( num_luns += 1 ))
14526                                 tot_len=0
14527                         fi
14528                 fi
14529                 (( tot_len += ext_len ))
14530                 last_lun=$frag_lun
14531         done
14532         if (( num_luns != 2 || tot_len != 512 )); then
14533                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14534                 return
14535         fi
14536
14537         echo "FIEMAP on 2-stripe file with hole succeeded"
14538 }
14539 run_test 130c "FIEMAP (2-stripe file with hole)"
14540
14541 test_130d() {
14542         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14543
14544         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14545         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14546         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14547                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14548
14549         trap cleanup_130 EXIT RETURN
14550
14551         local fm_file=$DIR/$tfile
14552         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14553                         error "setstripe on $fm_file"
14554
14555         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14556         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14557                 error "dd failed on $fm_file"
14558
14559         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14560         filefrag_op=$(filefrag -ve -k $fm_file |
14561                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14562
14563         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14564                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14565
14566         IFS=$'\n'
14567         local tot_len=0
14568         local num_luns=1
14569         for line in $filefrag_op; do
14570                 local frag_lun=$(echo $line | cut -d: -f5 |
14571                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14572                 local ext_len=$(echo $line | cut -d: -f4)
14573                 if (( $frag_lun != $last_lun )); then
14574                         if (( tot_len != 1024 )); then
14575                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14576                                 return
14577                         else
14578                                 (( num_luns += 1 ))
14579                                 local tot_len=0
14580                         fi
14581                 fi
14582                 (( tot_len += ext_len ))
14583                 last_lun=$frag_lun
14584         done
14585         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14586                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14587                 return
14588         fi
14589
14590         echo "FIEMAP on N-stripe file succeeded"
14591 }
14592 run_test 130d "FIEMAP (N-stripe file)"
14593
14594 test_130e() {
14595         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14596
14597         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14598         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14599         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14600                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14601
14602         trap cleanup_130 EXIT RETURN
14603
14604         local fm_file=$DIR/$tfile
14605         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14606
14607         local num_blks=512
14608         local expected_len=$(( (num_blks / 2) * 64 ))
14609         for ((i = 0; i < $num_blks; i++)); do
14610                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14611                         conv=notrunc > /dev/null 2>&1
14612         done
14613
14614         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14615         filefrag_op=$(filefrag -ve -k $fm_file |
14616                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14617
14618         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14619
14620         IFS=$'\n'
14621         local tot_len=0
14622         local num_luns=1
14623         for line in $filefrag_op; do
14624                 local frag_lun=$(echo $line | cut -d: -f5)
14625                 local ext_len=$(echo $line | cut -d: -f4)
14626                 if (( $frag_lun != $last_lun )); then
14627                         if (( tot_len != $expected_len )); then
14628                                 error "OST$last_lun $tot_len != $expected_len"
14629                         else
14630                                 (( num_luns += 1 ))
14631                                 tot_len=0
14632                         fi
14633                 fi
14634                 (( tot_len += ext_len ))
14635                 last_lun=$frag_lun
14636         done
14637         if (( num_luns != 2 || tot_len != $expected_len )); then
14638                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14639         fi
14640
14641         echo "FIEMAP with continuation calls succeeded"
14642 }
14643 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14644
14645 test_130f() {
14646         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14647         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14648         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14649                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14650
14651         local fm_file=$DIR/$tfile
14652         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14653                 error "multiop create with lov_delay_create on $fm_file"
14654
14655         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14656         filefrag_extents=$(filefrag -vek $fm_file |
14657                            awk '/extents? found/ { print $2 }')
14658         if (( $filefrag_extents != 0 )); then
14659                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14660         fi
14661
14662         rm -f $fm_file
14663 }
14664 run_test 130f "FIEMAP (unstriped file)"
14665
14666 test_130g() {
14667         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14668                 skip "Need MDS version with at least 2.12.53 for overstriping"
14669         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14670         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14671         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14672                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14673
14674         local file=$DIR/$tfile
14675         local nr=$((OSTCOUNT * 100))
14676
14677         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14678
14679         stack_trap "rm -f $file"
14680         dd if=/dev/zero of=$file count=$nr bs=1M
14681         sync
14682         nr=$($LFS getstripe -c $file)
14683
14684         local extents=$(filefrag -v $file |
14685                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14686
14687         echo "filefrag list $extents extents in file with stripecount $nr"
14688         if (( extents < nr )); then
14689                 $LFS getstripe $file
14690                 filefrag -v $file
14691                 error "filefrag printed $extents < $nr extents"
14692         fi
14693 }
14694 run_test 130g "FIEMAP (overstripe file)"
14695
14696 # Test for writev/readv
14697 test_131a() {
14698         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14699                 error "writev test failed"
14700         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14701                 error "readv failed"
14702         rm -f $DIR/$tfile
14703 }
14704 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14705
14706 test_131b() {
14707         local fsize=$((524288 + 1048576 + 1572864))
14708         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14709                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14710                         error "append writev test failed"
14711
14712         ((fsize += 1572864 + 1048576))
14713         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14714                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14715                         error "append writev test failed"
14716         rm -f $DIR/$tfile
14717 }
14718 run_test 131b "test append writev"
14719
14720 test_131c() {
14721         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14722         error "NOT PASS"
14723 }
14724 run_test 131c "test read/write on file w/o objects"
14725
14726 test_131d() {
14727         rwv -f $DIR/$tfile -w -n 1 1572864
14728         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14729         if [ "$NOB" != 1572864 ]; then
14730                 error "Short read filed: read $NOB bytes instead of 1572864"
14731         fi
14732         rm -f $DIR/$tfile
14733 }
14734 run_test 131d "test short read"
14735
14736 test_131e() {
14737         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14738         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14739         error "read hitting hole failed"
14740         rm -f $DIR/$tfile
14741 }
14742 run_test 131e "test read hitting hole"
14743
14744 check_stats() {
14745         local facet=$1
14746         local op=$2
14747         local want=${3:-0}
14748         local res
14749
14750         # open             11 samples [usecs] 468 4793 13658 35791898
14751         case $facet in
14752         mds*) res=($(do_facet $facet \
14753                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14754                  ;;
14755         ost*) res=($(do_facet $facet \
14756                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14757                  ;;
14758         *) error "Wrong facet '$facet'" ;;
14759         esac
14760         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14761         # if $want is zero, it means any stat increment is ok.
14762         if (( $want > 0 )); then
14763                 local count=${res[1]}
14764
14765                 if (( $count != $want )); then
14766                         if [[ $facet =~ "mds" ]]; then
14767                                 do_nodes $(comma_list $(mdts_nodes)) \
14768                                         $LCTL get_param mdt.*.md_stats
14769                         else
14770                                 do_nodes $(comma_list $(osts-nodes)) \
14771                                         $LCTL get_param obdfilter.*.stats
14772                         fi
14773                         error "The $op counter on $facet is $count, not $want"
14774                 fi
14775         fi
14776 }
14777
14778 test_133a() {
14779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14780         remote_ost_nodsh && skip "remote OST with nodsh"
14781         remote_mds_nodsh && skip "remote MDS with nodsh"
14782         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14783                 skip_env "MDS doesn't support rename stats"
14784
14785         local testdir=$DIR/${tdir}/stats_testdir
14786
14787         mkdir -p $DIR/${tdir}
14788
14789         # clear stats.
14790         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14791         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14792
14793         # verify mdt stats first.
14794         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14795         check_stats $SINGLEMDS "mkdir" 1
14796
14797         # clear "open" from "lfs mkdir" above
14798         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14799         touch ${testdir}/${tfile} || error "touch failed"
14800         check_stats $SINGLEMDS "open" 1
14801         check_stats $SINGLEMDS "close" 1
14802         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14803                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14804                 check_stats $SINGLEMDS "mknod" 2
14805         }
14806         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14807         check_stats $SINGLEMDS "unlink" 1
14808         rm -f ${testdir}/${tfile} || error "file remove failed"
14809         check_stats $SINGLEMDS "unlink" 2
14810
14811         # remove working dir and check mdt stats again.
14812         rmdir ${testdir} || error "rmdir failed"
14813         check_stats $SINGLEMDS "rmdir" 1
14814
14815         local testdir1=$DIR/${tdir}/stats_testdir1
14816         mkdir_on_mdt0 -p ${testdir}
14817         mkdir_on_mdt0 -p ${testdir1}
14818         touch ${testdir1}/test1
14819         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14820         check_stats $SINGLEMDS "crossdir_rename" 1
14821
14822         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14823         check_stats $SINGLEMDS "samedir_rename" 1
14824
14825         rm -rf $DIR/${tdir}
14826 }
14827 run_test 133a "Verifying MDT stats ========================================"
14828
14829 test_133b() {
14830         local res
14831
14832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14833         remote_ost_nodsh && skip "remote OST with nodsh"
14834         remote_mds_nodsh && skip "remote MDS with nodsh"
14835
14836         local testdir=$DIR/${tdir}/stats_testdir
14837
14838         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14839         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14840         touch ${testdir}/${tfile} || error "touch failed"
14841         cancel_lru_locks mdc
14842
14843         # clear stats.
14844         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14845         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14846
14847         # extra mdt stats verification.
14848         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14849         check_stats $SINGLEMDS "setattr" 1
14850         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14851         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14852         then            # LU-1740
14853                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14854                 check_stats $SINGLEMDS "getattr" 1
14855         fi
14856         rm -rf $DIR/${tdir}
14857
14858         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14859         # so the check below is not reliable
14860         [ $MDSCOUNT -eq 1 ] || return 0
14861
14862         # Sleep to avoid a cached response.
14863         #define OBD_STATFS_CACHE_SECONDS 1
14864         sleep 2
14865         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14866         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14867         $LFS df || error "lfs failed"
14868         check_stats $SINGLEMDS "statfs" 1
14869
14870         # check aggregated statfs (LU-10018)
14871         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14872                 return 0
14873         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14874                 return 0
14875         sleep 2
14876         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14877         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14878         df $DIR
14879         check_stats $SINGLEMDS "statfs" 1
14880
14881         # We want to check that the client didn't send OST_STATFS to
14882         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14883         # extra care is needed here.
14884         if remote_mds; then
14885                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14886                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14887
14888                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14889                 [ "$res" ] && error "OST got STATFS"
14890         fi
14891
14892         return 0
14893 }
14894 run_test 133b "Verifying extra MDT stats =================================="
14895
14896 test_133c() {
14897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14898         remote_ost_nodsh && skip "remote OST with nodsh"
14899         remote_mds_nodsh && skip "remote MDS with nodsh"
14900
14901         local testdir=$DIR/$tdir/stats_testdir
14902
14903         test_mkdir -p $testdir
14904
14905         # verify obdfilter stats.
14906         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14907         sync
14908         cancel_lru_locks osc
14909         wait_delete_completed
14910
14911         # clear stats.
14912         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14913         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14914
14915         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14916                 error "dd failed"
14917         sync
14918         cancel_lru_locks osc
14919         check_stats ost1 "write" 1
14920
14921         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14922         check_stats ost1 "read" 1
14923
14924         > $testdir/$tfile || error "truncate failed"
14925         check_stats ost1 "punch" 1
14926
14927         rm -f $testdir/$tfile || error "file remove failed"
14928         wait_delete_completed
14929         check_stats ost1 "destroy" 1
14930
14931         rm -rf $DIR/$tdir
14932 }
14933 run_test 133c "Verifying OST stats ========================================"
14934
14935 order_2() {
14936         local value=$1
14937         local orig=$value
14938         local order=1
14939
14940         while [ $value -ge 2 ]; do
14941                 order=$((order*2))
14942                 value=$((value/2))
14943         done
14944
14945         if [ $orig -gt $order ]; then
14946                 order=$((order*2))
14947         fi
14948         echo $order
14949 }
14950
14951 size_in_KMGT() {
14952     local value=$1
14953     local size=('K' 'M' 'G' 'T');
14954     local i=0
14955     local size_string=$value
14956
14957     while [ $value -ge 1024 ]; do
14958         if [ $i -gt 3 ]; then
14959             #T is the biggest unit we get here, if that is bigger,
14960             #just return XXXT
14961             size_string=${value}T
14962             break
14963         fi
14964         value=$((value >> 10))
14965         if [ $value -lt 1024 ]; then
14966             size_string=${value}${size[$i]}
14967             break
14968         fi
14969         i=$((i + 1))
14970     done
14971
14972     echo $size_string
14973 }
14974
14975 get_rename_size() {
14976         local size=$1
14977         local context=${2:-.}
14978         local sample=$(do_facet $SINGLEMDS $LCTL \
14979                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14980                 grep -A1 $context |
14981                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14982         echo $sample
14983 }
14984
14985 test_133d() {
14986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14987         remote_ost_nodsh && skip "remote OST with nodsh"
14988         remote_mds_nodsh && skip "remote MDS with nodsh"
14989         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14990                 skip_env "MDS doesn't support rename stats"
14991
14992         local testdir1=$DIR/${tdir}/stats_testdir1
14993         local testdir2=$DIR/${tdir}/stats_testdir2
14994         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14995
14996         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14997
14998         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14999         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15000
15001         createmany -o $testdir1/test 512 || error "createmany failed"
15002
15003         # check samedir rename size
15004         mv ${testdir1}/test0 ${testdir1}/test_0
15005
15006         local testdir1_size=$(ls -l $DIR/${tdir} |
15007                 awk '/stats_testdir1/ {print $5}')
15008         local 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         local cmd="do_facet $SINGLEMDS $LCTL "
15021         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15022
15023         eval $cmd || error "$cmd failed"
15024         local samedir=$($cmd | grep 'same_dir')
15025         local same_sample=$(get_rename_size $testdir1_size)
15026         [ -z "$samedir" ] && error "samedir_rename_size count error"
15027         [[ $same_sample -eq 1 ]] ||
15028                 error "samedir_rename_size error $same_sample"
15029         echo "Check same dir rename stats success"
15030
15031         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15032
15033         # check crossdir rename size
15034         mv ${testdir1}/test_0 ${testdir2}/test_0
15035
15036         testdir1_size=$(ls -l $DIR/${tdir} |
15037                 awk '/stats_testdir1/ {print $5}')
15038         testdir2_size=$(ls -l $DIR/${tdir} |
15039                 awk '/stats_testdir2/ {print $5}')
15040
15041         testdir1_size=$(order_2 $testdir1_size)
15042         testdir2_size=$(order_2 $testdir2_size)
15043
15044         testdir1_size=$(size_in_KMGT $testdir1_size)
15045         testdir2_size=$(size_in_KMGT $testdir2_size)
15046
15047         echo "source rename dir size: ${testdir1_size}"
15048         echo "target rename dir size: ${testdir2_size}"
15049
15050         eval $cmd || error "$cmd failed"
15051         local crossdir=$($cmd | grep 'crossdir')
15052         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15053         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15054         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15055         [[ $src_sample -eq 1 ]] ||
15056                 error "crossdir_rename_size error $src_sample"
15057         [[ $tgt_sample -eq 1 ]] ||
15058                 error "crossdir_rename_size error $tgt_sample"
15059         echo "Check cross dir rename stats success"
15060         rm -rf $DIR/${tdir}
15061 }
15062 run_test 133d "Verifying rename_stats ========================================"
15063
15064 test_133e() {
15065         remote_mds_nodsh && skip "remote MDS with nodsh"
15066         remote_ost_nodsh && skip "remote OST with nodsh"
15067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15068
15069         local testdir=$DIR/${tdir}/stats_testdir
15070         local ctr f0 f1 bs=32768 count=42 sum
15071
15072         mkdir -p ${testdir} || error "mkdir failed"
15073
15074         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15075
15076         for ctr in {write,read}_bytes; do
15077                 sync
15078                 cancel_lru_locks osc
15079
15080                 do_facet ost1 $LCTL set_param -n \
15081                         "obdfilter.*.exports.clear=clear"
15082
15083                 if [ $ctr = write_bytes ]; then
15084                         f0=/dev/zero
15085                         f1=${testdir}/${tfile}
15086                 else
15087                         f0=${testdir}/${tfile}
15088                         f1=/dev/null
15089                 fi
15090
15091                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15092                         error "dd failed"
15093                 sync
15094                 cancel_lru_locks osc
15095
15096                 sum=$(do_facet ost1 $LCTL get_param \
15097                         "obdfilter.*.exports.*.stats" |
15098                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15099                                 $1 == ctr { sum += $7 }
15100                                 END { printf("%0.0f", sum) }')
15101
15102                 if ((sum != bs * count)); then
15103                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15104                 fi
15105         done
15106
15107         rm -rf $DIR/${tdir}
15108 }
15109 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15110
15111 test_133f() {
15112         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15113                 skip "too old lustre for get_param -R ($facet_ver)"
15114
15115         # verifying readability.
15116         $LCTL get_param -R '*' &> /dev/null
15117
15118         # Verifing writability with badarea_io.
15119         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15120         local skipped_params='force_lbug|changelog_mask|daemon_file'
15121         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15122                 egrep -v "$skipped_params" |
15123                 xargs -n 1 find $proc_dirs -name |
15124                 xargs -n 1 badarea_io ||
15125                 error "client badarea_io failed"
15126
15127         # remount the FS in case writes/reads /proc break the FS
15128         cleanup || error "failed to unmount"
15129         setup || error "failed to setup"
15130 }
15131 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15132
15133 test_133g() {
15134         remote_mds_nodsh && skip "remote MDS with nodsh"
15135         remote_ost_nodsh && skip "remote OST with nodsh"
15136
15137         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15138         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15139         local facet
15140         for facet in mds1 ost1; do
15141                 local facet_ver=$(lustre_version_code $facet)
15142                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15143                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15144                 else
15145                         log "$facet: too old lustre for get_param -R"
15146                 fi
15147                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15148                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15149                                 tr -d = | egrep -v $skipped_params |
15150                                 xargs -n 1 find $proc_dirs -name |
15151                                 xargs -n 1 badarea_io" ||
15152                                         error "$facet badarea_io failed"
15153                 else
15154                         skip_noexit "$facet: too old lustre for get_param -R"
15155                 fi
15156         done
15157
15158         # remount the FS in case writes/reads /proc break the FS
15159         cleanup || error "failed to unmount"
15160         setup || error "failed to setup"
15161 }
15162 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15163
15164 test_133h() {
15165         remote_mds_nodsh && skip "remote MDS with nodsh"
15166         remote_ost_nodsh && skip "remote OST with nodsh"
15167         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15168                 skip "Need MDS version at least 2.9.54"
15169
15170         local facet
15171         for facet in client mds1 ost1; do
15172                 # Get the list of files that are missing the terminating newline
15173                 local plist=$(do_facet $facet
15174                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15175                 local ent
15176                 for ent in $plist; do
15177                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15178                                 awk -v FS='\v' -v RS='\v\v' \
15179                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15180                                         print FILENAME}'" 2>/dev/null)
15181                         [ -z $missing ] || {
15182                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15183                                 error "file does not end with newline: $facet-$ent"
15184                         }
15185                 done
15186         done
15187 }
15188 run_test 133h "Proc files should end with newlines"
15189
15190 test_134a() {
15191         remote_mds_nodsh && skip "remote MDS with nodsh"
15192         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15193                 skip "Need MDS version at least 2.7.54"
15194
15195         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15196         cancel_lru_locks mdc
15197
15198         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15199         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15200         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15201
15202         local nr=1000
15203         createmany -o $DIR/$tdir/f $nr ||
15204                 error "failed to create $nr files in $DIR/$tdir"
15205         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15206
15207         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15208         do_facet mds1 $LCTL set_param fail_loc=0x327
15209         do_facet mds1 $LCTL set_param fail_val=500
15210         touch $DIR/$tdir/m
15211
15212         echo "sleep 10 seconds ..."
15213         sleep 10
15214         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15215
15216         do_facet mds1 $LCTL set_param fail_loc=0
15217         do_facet mds1 $LCTL set_param fail_val=0
15218         [ $lck_cnt -lt $unused ] ||
15219                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15220
15221         rm $DIR/$tdir/m
15222         unlinkmany $DIR/$tdir/f $nr
15223 }
15224 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15225
15226 test_134b() {
15227         remote_mds_nodsh && skip "remote MDS with nodsh"
15228         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15229                 skip "Need MDS version at least 2.7.54"
15230
15231         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15232         cancel_lru_locks mdc
15233
15234         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15235                         ldlm.lock_reclaim_threshold_mb)
15236         # disable reclaim temporarily
15237         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15238
15239         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15240         do_facet mds1 $LCTL set_param fail_loc=0x328
15241         do_facet mds1 $LCTL set_param fail_val=500
15242
15243         $LCTL set_param debug=+trace
15244
15245         local nr=600
15246         createmany -o $DIR/$tdir/f $nr &
15247         local create_pid=$!
15248
15249         echo "Sleep $TIMEOUT seconds ..."
15250         sleep $TIMEOUT
15251         if ! ps -p $create_pid  > /dev/null 2>&1; then
15252                 do_facet mds1 $LCTL set_param fail_loc=0
15253                 do_facet mds1 $LCTL set_param fail_val=0
15254                 do_facet mds1 $LCTL set_param \
15255                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15256                 error "createmany finished incorrectly!"
15257         fi
15258         do_facet mds1 $LCTL set_param fail_loc=0
15259         do_facet mds1 $LCTL set_param fail_val=0
15260         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15261         wait $create_pid || return 1
15262
15263         unlinkmany $DIR/$tdir/f $nr
15264 }
15265 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15266
15267 test_135() {
15268         remote_mds_nodsh && skip "remote MDS with nodsh"
15269         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15270                 skip "Need MDS version at least 2.13.50"
15271         local fname
15272
15273         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15274
15275 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15276         #set only one record at plain llog
15277         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15278
15279         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15280
15281         #fill already existed plain llog each 64767
15282         #wrapping whole catalog
15283         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15284
15285         createmany -o $DIR/$tdir/$tfile_ 64700
15286         for (( i = 0; i < 64700; i = i + 2 ))
15287         do
15288                 rm $DIR/$tdir/$tfile_$i &
15289                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15290                 local pid=$!
15291                 wait $pid
15292         done
15293
15294         #waiting osp synchronization
15295         wait_delete_completed
15296 }
15297 run_test 135 "Race catalog processing"
15298
15299 test_136() {
15300         remote_mds_nodsh && skip "remote MDS with nodsh"
15301         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15302                 skip "Need MDS version at least 2.13.50"
15303         local fname
15304
15305         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15306         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15307         #set only one record at plain llog
15308 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15309         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15310
15311         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15312
15313         #fill already existed 2 plain llogs each 64767
15314         #wrapping whole catalog
15315         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15316         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15317         wait_delete_completed
15318
15319         createmany -o $DIR/$tdir/$tfile_ 10
15320         sleep 25
15321
15322         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15323         for (( i = 0; i < 10; i = i + 3 ))
15324         do
15325                 rm $DIR/$tdir/$tfile_$i &
15326                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15327                 local pid=$!
15328                 wait $pid
15329                 sleep 7
15330                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15331         done
15332
15333         #waiting osp synchronization
15334         wait_delete_completed
15335 }
15336 run_test 136 "Race catalog processing 2"
15337
15338 test_140() { #bug-17379
15339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15340
15341         test_mkdir $DIR/$tdir
15342         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15343         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15344
15345         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15346         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15347         local i=0
15348         while i=$((i + 1)); do
15349                 test_mkdir $i
15350                 cd $i || error "Changing to $i"
15351                 ln -s ../stat stat || error "Creating stat symlink"
15352                 # Read the symlink until ELOOP present,
15353                 # not LBUGing the system is considered success,
15354                 # we didn't overrun the stack.
15355                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15356                 if [ $ret -ne 0 ]; then
15357                         if [ $ret -eq 40 ]; then
15358                                 break  # -ELOOP
15359                         else
15360                                 error "Open stat symlink"
15361                                         return
15362                         fi
15363                 fi
15364         done
15365         i=$((i - 1))
15366         echo "The symlink depth = $i"
15367         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15368                 error "Invalid symlink depth"
15369
15370         # Test recursive symlink
15371         ln -s symlink_self symlink_self
15372         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15373         echo "open symlink_self returns $ret"
15374         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15375 }
15376 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15377
15378 test_150a() {
15379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15380
15381         local TF="$TMP/$tfile"
15382
15383         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15384         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15385         cp $TF $DIR/$tfile
15386         cancel_lru_locks $OSC
15387         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15388         remount_client $MOUNT
15389         df -P $MOUNT
15390         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15391
15392         $TRUNCATE $TF 6000
15393         $TRUNCATE $DIR/$tfile 6000
15394         cancel_lru_locks $OSC
15395         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15396
15397         echo "12345" >>$TF
15398         echo "12345" >>$DIR/$tfile
15399         cancel_lru_locks $OSC
15400         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15401
15402         echo "12345" >>$TF
15403         echo "12345" >>$DIR/$tfile
15404         cancel_lru_locks $OSC
15405         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15406 }
15407 run_test 150a "truncate/append tests"
15408
15409 test_150b() {
15410         check_set_fallocate_or_skip
15411         local out
15412
15413         touch $DIR/$tfile
15414         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15415         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15416                 skip_eopnotsupp "$out|check_fallocate failed"
15417 }
15418 run_test 150b "Verify fallocate (prealloc) functionality"
15419
15420 test_150bb() {
15421         check_set_fallocate_or_skip
15422
15423         touch $DIR/$tfile
15424         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15425         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15426         > $DIR/$tfile
15427         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15428         # precomputed md5sum for 20MB of zeroes
15429         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15430         local sum=($(md5sum $DIR/$tfile))
15431
15432         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15433
15434         check_set_fallocate 1
15435
15436         > $DIR/$tfile
15437         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15438         sum=($(md5sum $DIR/$tfile))
15439
15440         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15441 }
15442 run_test 150bb "Verify fallocate modes both zero space"
15443
15444 test_150c() {
15445         check_set_fallocate_or_skip
15446         local striping="-c2"
15447
15448         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15449         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15450         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15451         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15452         local want=$((OSTCOUNT * 1048576))
15453
15454         # Must allocate all requested space, not more than 5% extra
15455         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15456                 error "bytes $bytes is not $want"
15457
15458         rm -f $DIR/$tfile
15459
15460         echo "verify fallocate on PFL file"
15461
15462         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15463
15464         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15465                 error "Create $DIR/$tfile failed"
15466         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15467         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15468         want=$((512 * 1048576))
15469
15470         # Must allocate all requested space, not more than 5% extra
15471         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15472                 error "bytes $bytes is not $want"
15473 }
15474 run_test 150c "Verify fallocate Size and Blocks"
15475
15476 test_150d() {
15477         check_set_fallocate_or_skip
15478         local striping="-c2"
15479
15480         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15481
15482         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15483         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15484                 error "setstripe failed"
15485         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15486         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15487         local want=$((OSTCOUNT * 1048576))
15488
15489         # Must allocate all requested space, not more than 5% extra
15490         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15491                 error "bytes $bytes is not $want"
15492 }
15493 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15494
15495 test_150e() {
15496         check_set_fallocate_or_skip
15497
15498         echo "df before:"
15499         $LFS df
15500         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15501         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15502                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15503
15504         # Find OST with Minimum Size
15505         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15506                        sort -un | head -1)
15507
15508         # Get 100MB per OST of the available space to reduce run time
15509         # else 60% of the available space if we are running SLOW tests
15510         if [ $SLOW == "no" ]; then
15511                 local space=$((1024 * 100 * OSTCOUNT))
15512         else
15513                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15514         fi
15515
15516         fallocate -l${space}k $DIR/$tfile ||
15517                 error "fallocate ${space}k $DIR/$tfile failed"
15518         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15519
15520         # get size immediately after fallocate. This should be correctly
15521         # updated
15522         local size=$(stat -c '%s' $DIR/$tfile)
15523         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15524
15525         # Sleep for a while for statfs to get updated. And not pull from cache.
15526         sleep 2
15527
15528         echo "df after fallocate:"
15529         $LFS df
15530
15531         (( size / 1024 == space )) || error "size $size != requested $space"
15532         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15533                 error "used $used < space $space"
15534
15535         rm $DIR/$tfile || error "rm failed"
15536         sync
15537         wait_delete_completed
15538
15539         echo "df after unlink:"
15540         $LFS df
15541 }
15542 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15543
15544 test_150f() {
15545         local size
15546         local blocks
15547         local want_size_before=20480 # in bytes
15548         local want_blocks_before=40 # 512 sized blocks
15549         local want_blocks_after=24  # 512 sized blocks
15550         local length=$(((want_blocks_before - want_blocks_after) * 512))
15551
15552         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15553                 skip "need at least 2.14.0 for fallocate punch"
15554
15555         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15556                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15557         fi
15558
15559         check_set_fallocate_or_skip
15560         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15561
15562         [[ "x$DOM" == "xyes" ]] &&
15563                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15564
15565         echo "Verify fallocate punch: Range within the file range"
15566         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15567                 error "dd failed for bs 4096 and count 5"
15568
15569         # Call fallocate with punch range which is within the file range
15570         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15571                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15572         # client must see changes immediately after fallocate
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 there is hole in file
15584         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15585         # precomputed md5sum
15586         local expect="4a9a834a2db02452929c0a348273b4aa"
15587
15588         cksum=($(md5sum $DIR/$tfile))
15589         [[ "${cksum[0]}" == "$expect" ]] ||
15590                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15591
15592         # Start second sub-case for fallocate punch.
15593         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15594         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15595                 error "dd failed for bs 4096 and count 5"
15596
15597         # Punch range less than block size will have no change in block count
15598         want_blocks_after=40  # 512 sized blocks
15599
15600         # Punch overlaps two blocks and less than blocksize
15601         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15602                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15603         size=$(stat -c '%s' $DIR/$tfile)
15604         blocks=$(stat -c '%b' $DIR/$tfile)
15605
15606         # Verify punch worked.
15607         (( blocks == want_blocks_after )) ||
15608                 error "punch failed: blocks $blocks != $want_blocks_after"
15609
15610         (( size == want_size_before )) ||
15611                 error "punch failed: size $size != $want_size_before"
15612
15613         # Verify if range is really zero'ed out. We expect Zeros.
15614         # precomputed md5sum
15615         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15616         cksum=($(md5sum $DIR/$tfile))
15617         [[ "${cksum[0]}" == "$expect" ]] ||
15618                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15619 }
15620 run_test 150f "Verify fallocate punch functionality"
15621
15622 test_150g() {
15623         local space
15624         local size
15625         local blocks
15626         local blocks_after
15627         local size_after
15628         local BS=4096 # Block size in bytes
15629
15630         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15631                 skip "need at least 2.14.0 for fallocate punch"
15632
15633         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15634                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15635         fi
15636
15637         check_set_fallocate_or_skip
15638         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15639
15640         if [[ "x$DOM" == "xyes" ]]; then
15641                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15642                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15643         else
15644                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15645                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15646         fi
15647
15648         # Get 100MB per OST of the available space to reduce run time
15649         # else 60% of the available space if we are running SLOW tests
15650         if [ $SLOW == "no" ]; then
15651                 space=$((1024 * 100 * OSTCOUNT))
15652         else
15653                 # Find OST with Minimum Size
15654                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15655                         sort -un | head -1)
15656                 echo "min size OST: $space"
15657                 space=$(((space * 60)/100 * OSTCOUNT))
15658         fi
15659         # space in 1k units, round to 4k blocks
15660         local blkcount=$((space * 1024 / $BS))
15661
15662         echo "Verify fallocate punch: Very large Range"
15663         fallocate -l${space}k $DIR/$tfile ||
15664                 error "fallocate ${space}k $DIR/$tfile failed"
15665         # write 1M at the end, start and in the middle
15666         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15667                 error "dd failed: bs $BS count 256"
15668         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15669                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15670         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15671                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15672
15673         # Gather stats.
15674         size=$(stat -c '%s' $DIR/$tfile)
15675
15676         # gather punch length.
15677         local punch_size=$((size - (BS * 2)))
15678
15679         echo "punch_size = $punch_size"
15680         echo "size - punch_size: $((size - punch_size))"
15681         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15682
15683         # Call fallocate to punch all except 2 blocks. We leave the
15684         # first and the last block
15685         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15686         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15687                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15688
15689         size_after=$(stat -c '%s' $DIR/$tfile)
15690         blocks_after=$(stat -c '%b' $DIR/$tfile)
15691
15692         # Verify punch worked.
15693         # Size should be kept
15694         (( size == size_after )) ||
15695                 error "punch failed: size $size != $size_after"
15696
15697         # two 4k data blocks to remain plus possible 1 extra extent block
15698         (( blocks_after <= ((BS / 512) * 3) )) ||
15699                 error "too many blocks remains: $blocks_after"
15700
15701         # Verify that file has hole between the first and the last blocks
15702         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15703         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15704
15705         echo "Hole at [$hole_start, $hole_end)"
15706         (( hole_start == BS )) ||
15707                 error "no hole at offset $BS after punch"
15708
15709         (( hole_end == BS + punch_size )) ||
15710                 error "data at offset $hole_end < $((BS + punch_size))"
15711 }
15712 run_test 150g "Verify fallocate punch on large range"
15713
15714 test_150h() {
15715         local file=$DIR/$tfile
15716         local size
15717
15718         check_set_fallocate_or_skip
15719         statx_supported || skip_env "Test must be statx() syscall supported"
15720
15721         # fallocate() does not update the size information on the MDT
15722         fallocate -l 16K $file || error "failed to fallocate $file"
15723         cancel_lru_locks $OSC
15724         # STATX with cached-always mode will not send glimpse RPCs to OST,
15725         # it uses the caching attrs on the client side as much as possible.
15726         size=$($STATX --cached=always -c %s $file)
15727         [ $size == 16384 ] ||
15728                 error "size after fallocate() is $size, expected 16384"
15729 }
15730 run_test 150h "Verify extend fallocate updates the file size"
15731
15732 #LU-2902 roc_hit was not able to read all values from lproc
15733 function roc_hit_init() {
15734         local list=$(comma_list $(osts_nodes))
15735         local dir=$DIR/$tdir-check
15736         local file=$dir/$tfile
15737         local BEFORE
15738         local AFTER
15739         local idx
15740
15741         test_mkdir $dir
15742         #use setstripe to do a write to every ost
15743         for i in $(seq 0 $((OSTCOUNT-1))); do
15744                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15745                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15746                 idx=$(printf %04x $i)
15747                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15748                         awk '$1 == "cache_access" {sum += $7}
15749                                 END { printf("%0.0f", sum) }')
15750
15751                 cancel_lru_locks osc
15752                 cat $file >/dev/null
15753
15754                 AFTER=$(get_osd_param $list *OST*$idx stats |
15755                         awk '$1 == "cache_access" {sum += $7}
15756                                 END { printf("%0.0f", sum) }')
15757
15758                 echo BEFORE:$BEFORE AFTER:$AFTER
15759                 if ! let "AFTER - BEFORE == 4"; then
15760                         rm -rf $dir
15761                         error "roc_hit is not safe to use"
15762                 fi
15763                 rm $file
15764         done
15765
15766         rm -rf $dir
15767 }
15768
15769 function roc_hit() {
15770         local list=$(comma_list $(osts_nodes))
15771         echo $(get_osd_param $list '' stats |
15772                 awk '$1 == "cache_hit" {sum += $7}
15773                         END { printf("%0.0f", sum) }')
15774 }
15775
15776 function set_cache() {
15777         local on=1
15778
15779         if [ "$2" == "off" ]; then
15780                 on=0;
15781         fi
15782         local list=$(comma_list $(osts_nodes))
15783         set_osd_param $list '' $1_cache_enable $on
15784
15785         cancel_lru_locks osc
15786 }
15787
15788 test_151() {
15789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15790         remote_ost_nodsh && skip "remote OST with nodsh"
15791
15792         local CPAGES=3
15793         local list=$(comma_list $(osts_nodes))
15794
15795         # check whether obdfilter is cache capable at all
15796         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15797                 skip "not cache-capable obdfilter"
15798         fi
15799
15800         # check cache is enabled on all obdfilters
15801         if get_osd_param $list '' read_cache_enable | grep 0; then
15802                 skip "oss cache is disabled"
15803         fi
15804
15805         set_osd_param $list '' writethrough_cache_enable 1
15806
15807         # check write cache is enabled on all obdfilters
15808         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15809                 skip "oss write cache is NOT enabled"
15810         fi
15811
15812         roc_hit_init
15813
15814         #define OBD_FAIL_OBD_NO_LRU  0x609
15815         do_nodes $list $LCTL set_param fail_loc=0x609
15816
15817         # pages should be in the case right after write
15818         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15819                 error "dd failed"
15820
15821         local BEFORE=$(roc_hit)
15822         cancel_lru_locks osc
15823         cat $DIR/$tfile >/dev/null
15824         local AFTER=$(roc_hit)
15825
15826         do_nodes $list $LCTL set_param fail_loc=0
15827
15828         if ! let "AFTER - BEFORE == CPAGES"; then
15829                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15830         fi
15831
15832         cancel_lru_locks osc
15833         # invalidates OST cache
15834         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15835         set_osd_param $list '' read_cache_enable 0
15836         cat $DIR/$tfile >/dev/null
15837
15838         # now data shouldn't be found in the cache
15839         BEFORE=$(roc_hit)
15840         cancel_lru_locks osc
15841         cat $DIR/$tfile >/dev/null
15842         AFTER=$(roc_hit)
15843         if let "AFTER - BEFORE != 0"; then
15844                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15845         fi
15846
15847         set_osd_param $list '' read_cache_enable 1
15848         rm -f $DIR/$tfile
15849 }
15850 run_test 151 "test cache on oss and controls ==============================="
15851
15852 test_152() {
15853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15854
15855         local TF="$TMP/$tfile"
15856
15857         # simulate ENOMEM during write
15858 #define OBD_FAIL_OST_NOMEM      0x226
15859         lctl set_param fail_loc=0x80000226
15860         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15861         cp $TF $DIR/$tfile
15862         sync || error "sync failed"
15863         lctl set_param fail_loc=0
15864
15865         # discard client's cache
15866         cancel_lru_locks osc
15867
15868         # simulate ENOMEM during read
15869         lctl set_param fail_loc=0x80000226
15870         cmp $TF $DIR/$tfile || error "cmp failed"
15871         lctl set_param fail_loc=0
15872
15873         rm -f $TF
15874 }
15875 run_test 152 "test read/write with enomem ============================"
15876
15877 test_153() {
15878         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15879 }
15880 run_test 153 "test if fdatasync does not crash ======================="
15881
15882 dot_lustre_fid_permission_check() {
15883         local fid=$1
15884         local ffid=$MOUNT/.lustre/fid/$fid
15885         local test_dir=$2
15886
15887         echo "stat fid $fid"
15888         stat $ffid || error "stat $ffid failed."
15889         echo "touch fid $fid"
15890         touch $ffid || error "touch $ffid failed."
15891         echo "write to fid $fid"
15892         cat /etc/hosts > $ffid || error "write $ffid failed."
15893         echo "read fid $fid"
15894         diff /etc/hosts $ffid || error "read $ffid failed."
15895         echo "append write to fid $fid"
15896         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15897         echo "rename fid $fid"
15898         mv $ffid $test_dir/$tfile.1 &&
15899                 error "rename $ffid to $tfile.1 should fail."
15900         touch $test_dir/$tfile.1
15901         mv $test_dir/$tfile.1 $ffid &&
15902                 error "rename $tfile.1 to $ffid should fail."
15903         rm -f $test_dir/$tfile.1
15904         echo "truncate fid $fid"
15905         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15906         echo "link fid $fid"
15907         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15908         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15909                 echo "setfacl fid $fid"
15910                 setfacl -R -m u:$USER0:rwx $ffid ||
15911                         error "setfacl $ffid failed"
15912                 echo "getfacl fid $fid"
15913                 getfacl $ffid || error "getfacl $ffid failed."
15914         fi
15915         echo "unlink fid $fid"
15916         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15917         echo "mknod fid $fid"
15918         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15919
15920         fid=[0xf00000400:0x1:0x0]
15921         ffid=$MOUNT/.lustre/fid/$fid
15922
15923         echo "stat non-exist fid $fid"
15924         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15925         echo "write to non-exist fid $fid"
15926         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15927         echo "link new fid $fid"
15928         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15929
15930         mkdir -p $test_dir/$tdir
15931         touch $test_dir/$tdir/$tfile
15932         fid=$($LFS path2fid $test_dir/$tdir)
15933         rc=$?
15934         [ $rc -ne 0 ] &&
15935                 error "error: could not get fid for $test_dir/$dir/$tfile."
15936
15937         ffid=$MOUNT/.lustre/fid/$fid
15938
15939         echo "ls $fid"
15940         ls $ffid || error "ls $ffid failed."
15941         echo "touch $fid/$tfile.1"
15942         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15943
15944         echo "touch $MOUNT/.lustre/fid/$tfile"
15945         touch $MOUNT/.lustre/fid/$tfile && \
15946                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15947
15948         echo "setxattr to $MOUNT/.lustre/fid"
15949         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15950
15951         echo "listxattr for $MOUNT/.lustre/fid"
15952         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15953
15954         echo "delxattr from $MOUNT/.lustre/fid"
15955         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15956
15957         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15958         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15959                 error "touch invalid fid should fail."
15960
15961         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15962         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15963                 error "touch non-normal fid should fail."
15964
15965         echo "rename $tdir to $MOUNT/.lustre/fid"
15966         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15967                 error "rename to $MOUNT/.lustre/fid should fail."
15968
15969         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15970         then            # LU-3547
15971                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15972                 local new_obf_mode=777
15973
15974                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15975                 chmod $new_obf_mode $DIR/.lustre/fid ||
15976                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15977
15978                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15979                 [ $obf_mode -eq $new_obf_mode ] ||
15980                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15981
15982                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15983                 chmod $old_obf_mode $DIR/.lustre/fid ||
15984                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15985         fi
15986
15987         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15988         fid=$($LFS path2fid $test_dir/$tfile-2)
15989
15990         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15991         then # LU-5424
15992                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15993                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15994                         error "create lov data thru .lustre failed"
15995         fi
15996         echo "cp /etc/passwd $test_dir/$tfile-2"
15997         cp /etc/passwd $test_dir/$tfile-2 ||
15998                 error "copy to $test_dir/$tfile-2 failed."
15999         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16000         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16001                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16002
16003         rm -rf $test_dir/tfile.lnk
16004         rm -rf $test_dir/$tfile-2
16005 }
16006
16007 test_154A() {
16008         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16009                 skip "Need MDS version at least 2.4.1"
16010
16011         local tf=$DIR/$tfile
16012         touch $tf
16013
16014         local fid=$($LFS path2fid $tf)
16015         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16016
16017         # check that we get the same pathname back
16018         local rootpath
16019         local found
16020         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16021                 echo "$rootpath $fid"
16022                 found=$($LFS fid2path $rootpath "$fid")
16023                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16024                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16025         done
16026
16027         # check wrong root path format
16028         rootpath=$MOUNT"_wrong"
16029         found=$($LFS fid2path $rootpath "$fid")
16030         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16031 }
16032 run_test 154A "lfs path2fid and fid2path basic checks"
16033
16034 test_154B() {
16035         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16036                 skip "Need MDS version at least 2.4.1"
16037
16038         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16039         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16040         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16041         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16042
16043         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16044         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16045
16046         # check that we get the same pathname
16047         echo "PFID: $PFID, name: $name"
16048         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16049         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16050         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16051                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16052
16053         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16054 }
16055 run_test 154B "verify the ll_decode_linkea tool"
16056
16057 test_154a() {
16058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16059         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16060         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16061                 skip "Need MDS version at least 2.2.51"
16062         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16063
16064         cp /etc/hosts $DIR/$tfile
16065
16066         fid=$($LFS path2fid $DIR/$tfile)
16067         rc=$?
16068         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16069
16070         dot_lustre_fid_permission_check "$fid" $DIR ||
16071                 error "dot lustre permission check $fid failed"
16072
16073         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16074
16075         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16076
16077         touch $MOUNT/.lustre/file &&
16078                 error "creation is not allowed under .lustre"
16079
16080         mkdir $MOUNT/.lustre/dir &&
16081                 error "mkdir is not allowed under .lustre"
16082
16083         rm -rf $DIR/$tfile
16084 }
16085 run_test 154a "Open-by-FID"
16086
16087 test_154b() {
16088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16089         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16091         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16092                 skip "Need MDS version at least 2.2.51"
16093
16094         local remote_dir=$DIR/$tdir/remote_dir
16095         local MDTIDX=1
16096         local rc=0
16097
16098         mkdir -p $DIR/$tdir
16099         $LFS mkdir -i $MDTIDX $remote_dir ||
16100                 error "create remote directory failed"
16101
16102         cp /etc/hosts $remote_dir/$tfile
16103
16104         fid=$($LFS path2fid $remote_dir/$tfile)
16105         rc=$?
16106         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16107
16108         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16109                 error "dot lustre permission check $fid failed"
16110         rm -rf $DIR/$tdir
16111 }
16112 run_test 154b "Open-by-FID for remote directory"
16113
16114 test_154c() {
16115         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16116                 skip "Need MDS version at least 2.4.1"
16117
16118         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16119         local FID1=$($LFS path2fid $DIR/$tfile.1)
16120         local FID2=$($LFS path2fid $DIR/$tfile.2)
16121         local FID3=$($LFS path2fid $DIR/$tfile.3)
16122
16123         local N=1
16124         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16125                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16126                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16127                 local want=FID$N
16128                 [ "$FID" = "${!want}" ] ||
16129                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16130                 N=$((N + 1))
16131         done
16132
16133         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16134         do
16135                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16136                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16137                 N=$((N + 1))
16138         done
16139 }
16140 run_test 154c "lfs path2fid and fid2path multiple arguments"
16141
16142 test_154d() {
16143         remote_mds_nodsh && skip "remote MDS with nodsh"
16144         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16145                 skip "Need MDS version at least 2.5.53"
16146
16147         if remote_mds; then
16148                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16149         else
16150                 nid="0@lo"
16151         fi
16152         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16153         local fd
16154         local cmd
16155
16156         rm -f $DIR/$tfile
16157         touch $DIR/$tfile
16158
16159         local fid=$($LFS path2fid $DIR/$tfile)
16160         # Open the file
16161         fd=$(free_fd)
16162         cmd="exec $fd<$DIR/$tfile"
16163         eval $cmd
16164         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16165         echo "$fid_list" | grep "$fid"
16166         rc=$?
16167
16168         cmd="exec $fd>/dev/null"
16169         eval $cmd
16170         if [ $rc -ne 0 ]; then
16171                 error "FID $fid not found in open files list $fid_list"
16172         fi
16173 }
16174 run_test 154d "Verify open file fid"
16175
16176 test_154e()
16177 {
16178         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16179                 skip "Need MDS version at least 2.6.50"
16180
16181         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16182                 error ".lustre returned by readdir"
16183         fi
16184 }
16185 run_test 154e ".lustre is not returned by readdir"
16186
16187 test_154f() {
16188         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16189
16190         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16191         mkdir_on_mdt0 $DIR/$tdir
16192         # test dirs inherit from its stripe
16193         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16194         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16195         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16196         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16197         touch $DIR/f
16198
16199         # get fid of parents
16200         local FID0=$($LFS path2fid $DIR/$tdir)
16201         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16202         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16203         local FID3=$($LFS path2fid $DIR)
16204
16205         # check that path2fid --parents returns expected <parent_fid>/name
16206         # 1) test for a directory (single parent)
16207         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16208         [ "$parent" == "$FID0/foo1" ] ||
16209                 error "expected parent: $FID0/foo1, got: $parent"
16210
16211         # 2) test for a file with nlink > 1 (multiple parents)
16212         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16213         echo "$parent" | grep -F "$FID1/$tfile" ||
16214                 error "$FID1/$tfile not returned in parent list"
16215         echo "$parent" | grep -F "$FID2/link" ||
16216                 error "$FID2/link not returned in parent list"
16217
16218         # 3) get parent by fid
16219         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16220         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16221         echo "$parent" | grep -F "$FID1/$tfile" ||
16222                 error "$FID1/$tfile not returned in parent list (by fid)"
16223         echo "$parent" | grep -F "$FID2/link" ||
16224                 error "$FID2/link not returned in parent list (by fid)"
16225
16226         # 4) test for entry in root directory
16227         parent=$($LFS path2fid --parents $DIR/f)
16228         echo "$parent" | grep -F "$FID3/f" ||
16229                 error "$FID3/f not returned in parent list"
16230
16231         # 5) test it on root directory
16232         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16233                 error "$MOUNT should not have parents"
16234
16235         # enable xattr caching and check that linkea is correctly updated
16236         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16237         save_lustre_params client "llite.*.xattr_cache" > $save
16238         lctl set_param llite.*.xattr_cache 1
16239
16240         # 6.1) linkea update on rename
16241         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16242
16243         # get parents by fid
16244         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16245         # foo1 should no longer be returned in parent list
16246         echo "$parent" | grep -F "$FID1" &&
16247                 error "$FID1 should no longer be in parent list"
16248         # the new path should appear
16249         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16250                 error "$FID2/$tfile.moved is not in parent list"
16251
16252         # 6.2) linkea update on unlink
16253         rm -f $DIR/$tdir/foo2/link
16254         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16255         # foo2/link should no longer be returned in parent list
16256         echo "$parent" | grep -F "$FID2/link" &&
16257                 error "$FID2/link should no longer be in parent list"
16258         true
16259
16260         rm -f $DIR/f
16261         restore_lustre_params < $save
16262         rm -f $save
16263 }
16264 run_test 154f "get parent fids by reading link ea"
16265
16266 test_154g()
16267 {
16268         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16269            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16270                 skip "Need MDS version at least 2.6.92"
16271
16272         mkdir_on_mdt0 $DIR/$tdir
16273         llapi_fid_test -d $DIR/$tdir
16274 }
16275 run_test 154g "various llapi FID tests"
16276
16277 test_154h()
16278 {
16279         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16280                 skip "Need client at least version 2.15.55.1"
16281
16282         # Create an empty file
16283         touch $DIR/$tfile
16284
16285         # Get FID (interactive mode) and save under $TMP/$tfile.log
16286         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16287                 path2fid $DIR/$tfile
16288         EOF
16289
16290         fid=$(cat $TMP/$tfile.log)
16291         # $fid should not be empty
16292         [[ ! -z $fid ]] || error "FID is empty"
16293         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16294 }
16295 run_test 154h "Verify interactive path2fid"
16296
16297 test_155_small_load() {
16298     local temp=$TMP/$tfile
16299     local file=$DIR/$tfile
16300
16301     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16302         error "dd of=$temp bs=6096 count=1 failed"
16303     cp $temp $file
16304     cancel_lru_locks $OSC
16305     cmp $temp $file || error "$temp $file differ"
16306
16307     $TRUNCATE $temp 6000
16308     $TRUNCATE $file 6000
16309     cmp $temp $file || error "$temp $file differ (truncate1)"
16310
16311     echo "12345" >>$temp
16312     echo "12345" >>$file
16313     cmp $temp $file || error "$temp $file differ (append1)"
16314
16315     echo "12345" >>$temp
16316     echo "12345" >>$file
16317     cmp $temp $file || error "$temp $file differ (append2)"
16318
16319     rm -f $temp $file
16320     true
16321 }
16322
16323 test_155_big_load() {
16324         remote_ost_nodsh && skip "remote OST with nodsh"
16325
16326         local temp=$TMP/$tfile
16327         local file=$DIR/$tfile
16328
16329         free_min_max
16330         local cache_size=$(do_facet ost$((MAXI+1)) \
16331                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16332
16333         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16334         # pre-set value
16335         if [ -z "$cache_size" ]; then
16336                 cache_size=256
16337         fi
16338         local large_file_size=$((cache_size * 2))
16339
16340         echo "OSS cache size: $cache_size KB"
16341         echo "Large file size: $large_file_size KB"
16342
16343         [ $MAXV -le $large_file_size ] &&
16344                 skip_env "max available OST size needs > $large_file_size KB"
16345
16346         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16347
16348         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16349                 error "dd of=$temp bs=$large_file_size count=1k failed"
16350         cp $temp $file
16351         ls -lh $temp $file
16352         cancel_lru_locks osc
16353         cmp $temp $file || error "$temp $file differ"
16354
16355         rm -f $temp $file
16356         true
16357 }
16358
16359 save_writethrough() {
16360         local facets=$(get_facets OST)
16361
16362         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16363 }
16364
16365 test_155a() {
16366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16367
16368         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16369
16370         save_writethrough $p
16371
16372         set_cache read on
16373         set_cache writethrough on
16374         test_155_small_load
16375         restore_lustre_params < $p
16376         rm -f $p
16377 }
16378 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16379
16380 test_155b() {
16381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16382
16383         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16384
16385         save_writethrough $p
16386
16387         set_cache read on
16388         set_cache writethrough off
16389         test_155_small_load
16390         restore_lustre_params < $p
16391         rm -f $p
16392 }
16393 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16394
16395 test_155c() {
16396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16397
16398         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16399
16400         save_writethrough $p
16401
16402         set_cache read off
16403         set_cache writethrough on
16404         test_155_small_load
16405         restore_lustre_params < $p
16406         rm -f $p
16407 }
16408 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16409
16410 test_155d() {
16411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16412
16413         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16414
16415         save_writethrough $p
16416
16417         set_cache read off
16418         set_cache writethrough off
16419         test_155_small_load
16420         restore_lustre_params < $p
16421         rm -f $p
16422 }
16423 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16424
16425 test_155e() {
16426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16427
16428         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16429
16430         save_writethrough $p
16431
16432         set_cache read on
16433         set_cache writethrough on
16434         test_155_big_load
16435         restore_lustre_params < $p
16436         rm -f $p
16437 }
16438 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16439
16440 test_155f() {
16441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16442
16443         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16444
16445         save_writethrough $p
16446
16447         set_cache read on
16448         set_cache writethrough off
16449         test_155_big_load
16450         restore_lustre_params < $p
16451         rm -f $p
16452 }
16453 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16454
16455 test_155g() {
16456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16457
16458         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16459
16460         save_writethrough $p
16461
16462         set_cache read off
16463         set_cache writethrough on
16464         test_155_big_load
16465         restore_lustre_params < $p
16466         rm -f $p
16467 }
16468 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16469
16470 test_155h() {
16471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16472
16473         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16474
16475         save_writethrough $p
16476
16477         set_cache read off
16478         set_cache writethrough off
16479         test_155_big_load
16480         restore_lustre_params < $p
16481         rm -f $p
16482 }
16483 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16484
16485 test_156() {
16486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16487         remote_ost_nodsh && skip "remote OST with nodsh"
16488         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16489                 skip "stats not implemented on old servers"
16490         [ "$ost1_FSTYPE" = "zfs" ] &&
16491                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16492
16493         local CPAGES=3
16494         local BEFORE
16495         local AFTER
16496         local file="$DIR/$tfile"
16497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16498
16499         save_writethrough $p
16500         roc_hit_init
16501
16502         log "Turn on read and write cache"
16503         set_cache read on
16504         set_cache writethrough on
16505
16506         log "Write data and read it back."
16507         log "Read should be satisfied from the cache."
16508         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16509         BEFORE=$(roc_hit)
16510         cancel_lru_locks osc
16511         cat $file >/dev/null
16512         AFTER=$(roc_hit)
16513         if ! let "AFTER - BEFORE == CPAGES"; then
16514                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16515         else
16516                 log "cache hits: before: $BEFORE, after: $AFTER"
16517         fi
16518
16519         log "Read again; it should be satisfied from the cache."
16520         BEFORE=$AFTER
16521         cancel_lru_locks osc
16522         cat $file >/dev/null
16523         AFTER=$(roc_hit)
16524         if ! let "AFTER - BEFORE == CPAGES"; then
16525                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16526         else
16527                 log "cache hits:: before: $BEFORE, after: $AFTER"
16528         fi
16529
16530         log "Turn off the read cache and turn on the write cache"
16531         set_cache read off
16532         set_cache writethrough on
16533
16534         log "Read again; it should be satisfied from the cache."
16535         BEFORE=$(roc_hit)
16536         cancel_lru_locks osc
16537         cat $file >/dev/null
16538         AFTER=$(roc_hit)
16539         if ! let "AFTER - BEFORE == CPAGES"; then
16540                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16541         else
16542                 log "cache hits:: before: $BEFORE, after: $AFTER"
16543         fi
16544
16545         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16546                 # > 2.12.56 uses pagecache if cached
16547                 log "Read again; it should not be satisfied from the cache."
16548                 BEFORE=$AFTER
16549                 cancel_lru_locks osc
16550                 cat $file >/dev/null
16551                 AFTER=$(roc_hit)
16552                 if ! let "AFTER - BEFORE == 0"; then
16553                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16554                 else
16555                         log "cache hits:: before: $BEFORE, after: $AFTER"
16556                 fi
16557         fi
16558
16559         log "Write data and read it back."
16560         log "Read should be satisfied from the cache."
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 == CPAGES"; then
16567                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16568         else
16569                 log "cache hits:: before: $BEFORE, after: $AFTER"
16570         fi
16571
16572         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16573                 # > 2.12.56 uses pagecache if cached
16574                 log "Read again; it should not be satisfied from the cache."
16575                 BEFORE=$AFTER
16576                 cancel_lru_locks osc
16577                 cat $file >/dev/null
16578                 AFTER=$(roc_hit)
16579                 if ! let "AFTER - BEFORE == 0"; then
16580                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16581                 else
16582                         log "cache hits:: before: $BEFORE, after: $AFTER"
16583                 fi
16584         fi
16585
16586         log "Turn off read and write cache"
16587         set_cache read off
16588         set_cache writethrough off
16589
16590         log "Write data and read it back"
16591         log "It should not be satisfied from the cache."
16592         rm -f $file
16593         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16594         cancel_lru_locks osc
16595         BEFORE=$(roc_hit)
16596         cat $file >/dev/null
16597         AFTER=$(roc_hit)
16598         if ! let "AFTER - BEFORE == 0"; then
16599                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16600         else
16601                 log "cache hits:: before: $BEFORE, after: $AFTER"
16602         fi
16603
16604         log "Turn on the read cache and turn off the write cache"
16605         set_cache read on
16606         set_cache writethrough off
16607
16608         log "Write data and read it back"
16609         log "It should not be satisfied from the cache."
16610         rm -f $file
16611         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16612         BEFORE=$(roc_hit)
16613         cancel_lru_locks osc
16614         cat $file >/dev/null
16615         AFTER=$(roc_hit)
16616         if ! let "AFTER - BEFORE == 0"; then
16617                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16618         else
16619                 log "cache hits:: before: $BEFORE, after: $AFTER"
16620         fi
16621
16622         log "Read again; it should be satisfied from the cache."
16623         BEFORE=$(roc_hit)
16624         cancel_lru_locks osc
16625         cat $file >/dev/null
16626         AFTER=$(roc_hit)
16627         if ! let "AFTER - BEFORE == CPAGES"; then
16628                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16629         else
16630                 log "cache hits:: before: $BEFORE, after: $AFTER"
16631         fi
16632
16633         restore_lustre_params < $p
16634         rm -f $p $file
16635 }
16636 run_test 156 "Verification of tunables"
16637
16638 test_160a() {
16639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16640         remote_mds_nodsh && skip "remote MDS with nodsh"
16641         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16642                 skip "Need MDS version at least 2.2.0"
16643
16644         changelog_register || error "changelog_register failed"
16645         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16646         changelog_users $SINGLEMDS | grep -q $cl_user ||
16647                 error "User $cl_user not found in changelog_users"
16648
16649         mkdir_on_mdt0 $DIR/$tdir
16650
16651         # change something
16652         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16653         changelog_clear 0 || error "changelog_clear failed"
16654         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16655         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16656         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16657         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16658         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16659         rm $DIR/$tdir/pics/desktop.jpg
16660
16661         echo "verifying changelog mask"
16662         changelog_chmask "-MKDIR"
16663         changelog_chmask "-CLOSE"
16664
16665         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16666         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16667
16668         changelog_chmask "+MKDIR"
16669         changelog_chmask "+CLOSE"
16670
16671         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16672         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16673
16674         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16675         CLOSES=$(changelog_dump | grep -c "CLOSE")
16676         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16677         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16678
16679         # verify contents
16680         echo "verifying target fid"
16681         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16682         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16683         [ "$fidc" == "$fidf" ] ||
16684                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16685         echo "verifying parent fid"
16686         # The FID returned from the Changelog may be the directory shard on
16687         # a different MDT, and not the FID returned by path2fid on the parent.
16688         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16689         # since this is what will matter when recreating this file in the tree.
16690         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16691         local pathp=$($LFS fid2path $MOUNT "$fidp")
16692         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16693                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16694
16695         echo "getting records for $cl_user"
16696         changelog_users $SINGLEMDS
16697         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16698         local nclr=3
16699         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16700                 error "changelog_clear failed"
16701         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16702         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16703         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16704                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16705
16706         local min0_rec=$(changelog_users $SINGLEMDS |
16707                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16708         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16709                           awk '{ print $1; exit; }')
16710
16711         changelog_dump | tail -n 5
16712         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16713         [ $first_rec == $((min0_rec + 1)) ] ||
16714                 error "first index should be $min0_rec + 1 not $first_rec"
16715
16716         # LU-3446 changelog index reset on MDT restart
16717         local cur_rec1=$(changelog_users $SINGLEMDS |
16718                          awk '/^current.index:/ { print $NF }')
16719         changelog_clear 0 ||
16720                 error "clear all changelog records for $cl_user failed"
16721         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16722         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16723                 error "Fail to start $SINGLEMDS"
16724         local cur_rec2=$(changelog_users $SINGLEMDS |
16725                          awk '/^current.index:/ { print $NF }')
16726         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16727         [ $cur_rec1 == $cur_rec2 ] ||
16728                 error "current index should be $cur_rec1 not $cur_rec2"
16729
16730         echo "verifying users from this test are deregistered"
16731         changelog_deregister || error "changelog_deregister failed"
16732         changelog_users $SINGLEMDS | grep -q $cl_user &&
16733                 error "User '$cl_user' still in changelog_users"
16734
16735         # lctl get_param -n mdd.*.changelog_users
16736         # current_index: 144
16737         # ID    index (idle seconds)
16738         # cl3   144   (2) mask=<list>
16739         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16740                 # this is the normal case where all users were deregistered
16741                 # make sure no new records are added when no users are present
16742                 local last_rec1=$(changelog_users $SINGLEMDS |
16743                                   awk '/^current.index:/ { print $NF }')
16744                 touch $DIR/$tdir/chloe
16745                 local last_rec2=$(changelog_users $SINGLEMDS |
16746                                   awk '/^current.index:/ { print $NF }')
16747                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16748                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16749         else
16750                 # any changelog users must be leftovers from a previous test
16751                 changelog_users $SINGLEMDS
16752                 echo "other changelog users; can't verify off"
16753         fi
16754 }
16755 run_test 160a "changelog sanity"
16756
16757 test_160b() { # LU-3587
16758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16759         remote_mds_nodsh && skip "remote MDS with nodsh"
16760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16761                 skip "Need MDS version at least 2.2.0"
16762
16763         changelog_register || error "changelog_register failed"
16764         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16765         changelog_users $SINGLEMDS | grep -q $cl_user ||
16766                 error "User '$cl_user' not found in changelog_users"
16767
16768         local longname1=$(str_repeat a 255)
16769         local longname2=$(str_repeat b 255)
16770
16771         cd $DIR
16772         echo "creating very long named file"
16773         touch $longname1 || error "create of '$longname1' failed"
16774         echo "renaming very long named file"
16775         mv $longname1 $longname2
16776
16777         changelog_dump | grep RENME | tail -n 5
16778         rm -f $longname2
16779 }
16780 run_test 160b "Verify that very long rename doesn't crash in changelog"
16781
16782 test_160c() {
16783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16784         remote_mds_nodsh && skip "remote MDS with nodsh"
16785
16786         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16787                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16788                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16789                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16790
16791         local rc=0
16792
16793         # Registration step
16794         changelog_register || error "changelog_register failed"
16795
16796         rm -rf $DIR/$tdir
16797         mkdir -p $DIR/$tdir
16798         $MCREATE $DIR/$tdir/foo_160c
16799         changelog_chmask "-TRUNC"
16800         $TRUNCATE $DIR/$tdir/foo_160c 200
16801         changelog_chmask "+TRUNC"
16802         $TRUNCATE $DIR/$tdir/foo_160c 199
16803         changelog_dump | tail -n 5
16804         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16805         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16806 }
16807 run_test 160c "verify that changelog log catch the truncate event"
16808
16809 test_160d() {
16810         remote_mds_nodsh && skip "remote MDS with nodsh"
16811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16813         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16814                 skip "Need MDS version at least 2.7.60"
16815
16816         # Registration step
16817         changelog_register || error "changelog_register failed"
16818
16819         mkdir -p $DIR/$tdir/migrate_dir
16820         changelog_clear 0 || error "changelog_clear failed"
16821
16822         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16823         changelog_dump | tail -n 5
16824         local migrates=$(changelog_dump | grep -c "MIGRT")
16825         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16826 }
16827 run_test 160d "verify that changelog log catch the migrate event"
16828
16829 test_160e() {
16830         remote_mds_nodsh && skip "remote MDS with nodsh"
16831
16832         # Create a user
16833         changelog_register || error "changelog_register failed"
16834
16835         local MDT0=$(facet_svc $SINGLEMDS)
16836         local rc
16837
16838         # No user (expect fail)
16839         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16840         rc=$?
16841         if [ $rc -eq 0 ]; then
16842                 error "Should fail without user"
16843         elif [ $rc -ne 4 ]; then
16844                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16845         fi
16846
16847         # Delete a future user (expect fail)
16848         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16849         rc=$?
16850         if [ $rc -eq 0 ]; then
16851                 error "Deleted non-existant user cl77"
16852         elif [ $rc -ne 2 ]; then
16853                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16854         fi
16855
16856         # Clear to a bad index (1 billion should be safe)
16857         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16858         rc=$?
16859
16860         if [ $rc -eq 0 ]; then
16861                 error "Successfully cleared to invalid CL index"
16862         elif [ $rc -ne 22 ]; then
16863                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16864         fi
16865 }
16866 run_test 160e "changelog negative testing (should return errors)"
16867
16868 test_160f() {
16869         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16870         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16871                 skip "Need MDS version at least 2.10.56"
16872
16873         local mdts=$(comma_list $(mdts_nodes))
16874
16875         # Create a user
16876         changelog_register || error "first changelog_register failed"
16877         changelog_register || error "second changelog_register failed"
16878         local cl_users
16879         declare -A cl_user1
16880         declare -A cl_user2
16881         local user_rec1
16882         local user_rec2
16883         local i
16884
16885         # generate some changelog records to accumulate on each MDT
16886         # use all_char because created files should be evenly distributed
16887         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16888                 error "test_mkdir $tdir failed"
16889         log "$(date +%s): creating first files"
16890         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16891                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16892                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16893         done
16894
16895         # check changelogs have been generated
16896         local start=$SECONDS
16897         local idle_time=$((MDSCOUNT * 5 + 5))
16898         local nbcl=$(changelog_dump | wc -l)
16899         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16900
16901         for param in "changelog_max_idle_time=$idle_time" \
16902                      "changelog_gc=1" \
16903                      "changelog_min_gc_interval=2" \
16904                      "changelog_min_free_cat_entries=3"; do
16905                 local MDT0=$(facet_svc $SINGLEMDS)
16906                 local var="${param%=*}"
16907                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16908
16909                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16910                 do_nodes $mdts $LCTL set_param mdd.*.$param
16911         done
16912
16913         # force cl_user2 to be idle (1st part), but also cancel the
16914         # cl_user1 records so that it is not evicted later in the test.
16915         local sleep1=$((idle_time / 2))
16916         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16917         sleep $sleep1
16918
16919         # simulate changelog catalog almost full
16920         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16921         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16922
16923         for i in $(seq $MDSCOUNT); do
16924                 cl_users=(${CL_USERS[mds$i]})
16925                 cl_user1[mds$i]="${cl_users[0]}"
16926                 cl_user2[mds$i]="${cl_users[1]}"
16927
16928                 [ -n "${cl_user1[mds$i]}" ] ||
16929                         error "mds$i: no user registered"
16930                 [ -n "${cl_user2[mds$i]}" ] ||
16931                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16932
16933                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16934                 [ -n "$user_rec1" ] ||
16935                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16936                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16937                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16938                 [ -n "$user_rec2" ] ||
16939                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16940                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16941                      "$user_rec1 + 2 == $user_rec2"
16942                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16943                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16944                               "$user_rec1 + 2, but is $user_rec2"
16945                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16946                 [ -n "$user_rec2" ] ||
16947                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16948                 [ $user_rec1 == $user_rec2 ] ||
16949                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16950                               "$user_rec1, but is $user_rec2"
16951         done
16952
16953         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16954         local sleep2=$((idle_time - (SECONDS - start) + 1))
16955         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16956         sleep $sleep2
16957
16958         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16959         # cl_user1 should be OK because it recently processed records.
16960         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16961         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16962                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16963                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16964         done
16965
16966         # ensure gc thread is done
16967         for i in $(mdts_nodes); do
16968                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16969                         error "$i: GC-thread not done"
16970         done
16971
16972         local first_rec
16973         for (( i = 1; i <= MDSCOUNT; i++ )); do
16974                 # check cl_user1 still registered
16975                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16976                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16977                 # check cl_user2 unregistered
16978                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16979                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16980
16981                 # check changelogs are present and starting at $user_rec1 + 1
16982                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16983                 [ -n "$user_rec1" ] ||
16984                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16985                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16986                             awk '{ print $1; exit; }')
16987
16988                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16989                 [ $((user_rec1 + 1)) == $first_rec ] ||
16990                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16991         done
16992 }
16993 run_test 160f "changelog garbage collect (timestamped users)"
16994
16995 test_160g() {
16996         remote_mds_nodsh && skip "remote MDS with nodsh"
16997         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16998                 skip "Need MDS version at least 2.14.55"
16999
17000         local mdts=$(comma_list $(mdts_nodes))
17001
17002         # Create a user
17003         changelog_register || error "first changelog_register failed"
17004         changelog_register || error "second changelog_register failed"
17005         local cl_users
17006         declare -A cl_user1
17007         declare -A cl_user2
17008         local user_rec1
17009         local user_rec2
17010         local i
17011
17012         # generate some changelog records to accumulate on each MDT
17013         # use all_char because created files should be evenly distributed
17014         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17015                 error "test_mkdir $tdir failed"
17016         for ((i = 0; i < MDSCOUNT; i++)); do
17017                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17018                         error "create $DIR/$tdir/d$i.1 failed"
17019         done
17020
17021         # check changelogs have been generated
17022         local nbcl=$(changelog_dump | wc -l)
17023         (( $nbcl > 0 )) || error "no changelogs found"
17024
17025         # reduce the max_idle_indexes value to make sure we exceed it
17026         for param in "changelog_max_idle_indexes=2" \
17027                      "changelog_gc=1" \
17028                      "changelog_min_gc_interval=2"; do
17029                 local MDT0=$(facet_svc $SINGLEMDS)
17030                 local var="${param%=*}"
17031                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17032
17033                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17034                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17035                         error "unable to set mdd.*.$param"
17036         done
17037
17038         local start=$SECONDS
17039         for i in $(seq $MDSCOUNT); do
17040                 cl_users=(${CL_USERS[mds$i]})
17041                 cl_user1[mds$i]="${cl_users[0]}"
17042                 cl_user2[mds$i]="${cl_users[1]}"
17043
17044                 [ -n "${cl_user1[mds$i]}" ] ||
17045                         error "mds$i: user1 is not registered"
17046                 [ -n "${cl_user2[mds$i]}" ] ||
17047                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17048
17049                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17050                 [ -n "$user_rec1" ] ||
17051                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17052                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17053                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17054                 [ -n "$user_rec2" ] ||
17055                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17056                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17057                      "$user_rec1 + 2 == $user_rec2"
17058                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17059                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17060                               "expected $user_rec1 + 2, but is $user_rec2"
17061                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17062                 [ -n "$user_rec2" ] ||
17063                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17064                 [ $user_rec1 == $user_rec2 ] ||
17065                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17066                               "expected $user_rec1, but is $user_rec2"
17067         done
17068
17069         # ensure we are past the previous changelog_min_gc_interval set above
17070         local sleep2=$((start + 2 - SECONDS))
17071         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17072         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17073         # cl_user1 should be OK because it recently processed records.
17074         for ((i = 0; i < MDSCOUNT; i++)); do
17075                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17076                         error "create $DIR/$tdir/d$i.3 failed"
17077         done
17078
17079         # ensure gc thread is done
17080         for i in $(mdts_nodes); do
17081                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17082                         error "$i: GC-thread not done"
17083         done
17084
17085         local first_rec
17086         for (( i = 1; i <= MDSCOUNT; i++ )); do
17087                 # check cl_user1 still registered
17088                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17089                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17090                 # check cl_user2 unregistered
17091                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17092                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17093
17094                 # check changelogs are present and starting at $user_rec1 + 1
17095                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17096                 [ -n "$user_rec1" ] ||
17097                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17098                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17099                             awk '{ print $1; exit; }')
17100
17101                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17102                 [ $((user_rec1 + 1)) == $first_rec ] ||
17103                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17104         done
17105 }
17106 run_test 160g "changelog garbage collect on idle records"
17107
17108 test_160h() {
17109         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17110         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17111                 skip "Need MDS version at least 2.10.56"
17112
17113         local mdts=$(comma_list $(mdts_nodes))
17114
17115         # Create a user
17116         changelog_register || error "first changelog_register failed"
17117         changelog_register || error "second changelog_register failed"
17118         local cl_users
17119         declare -A cl_user1
17120         declare -A cl_user2
17121         local user_rec1
17122         local user_rec2
17123         local i
17124
17125         # generate some changelog records to accumulate on each MDT
17126         # use all_char because created files should be evenly distributed
17127         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17128                 error "test_mkdir $tdir failed"
17129         for ((i = 0; i < MDSCOUNT; i++)); do
17130                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17131                         error "create $DIR/$tdir/d$i.1 failed"
17132         done
17133
17134         # check changelogs have been generated
17135         local nbcl=$(changelog_dump | wc -l)
17136         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17137
17138         for param in "changelog_max_idle_time=10" \
17139                      "changelog_gc=1" \
17140                      "changelog_min_gc_interval=2"; do
17141                 local MDT0=$(facet_svc $SINGLEMDS)
17142                 local var="${param%=*}"
17143                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17144
17145                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17146                 do_nodes $mdts $LCTL set_param mdd.*.$param
17147         done
17148
17149         # force cl_user2 to be idle (1st part)
17150         sleep 9
17151
17152         for i in $(seq $MDSCOUNT); do
17153                 cl_users=(${CL_USERS[mds$i]})
17154                 cl_user1[mds$i]="${cl_users[0]}"
17155                 cl_user2[mds$i]="${cl_users[1]}"
17156
17157                 [ -n "${cl_user1[mds$i]}" ] ||
17158                         error "mds$i: no user registered"
17159                 [ -n "${cl_user2[mds$i]}" ] ||
17160                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17161
17162                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17163                 [ -n "$user_rec1" ] ||
17164                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17165                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17166                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17167                 [ -n "$user_rec2" ] ||
17168                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17169                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17170                      "$user_rec1 + 2 == $user_rec2"
17171                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17172                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17173                               "$user_rec1 + 2, but is $user_rec2"
17174                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17175                 [ -n "$user_rec2" ] ||
17176                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17177                 [ $user_rec1 == $user_rec2 ] ||
17178                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17179                               "$user_rec1, but is $user_rec2"
17180         done
17181
17182         # force cl_user2 to be idle (2nd part) and to reach
17183         # changelog_max_idle_time
17184         sleep 2
17185
17186         # force each GC-thread start and block then
17187         # one per MDT/MDD, set fail_val accordingly
17188         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17189         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17190
17191         # generate more changelogs to trigger fail_loc
17192         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17193                 error "create $DIR/$tdir/${tfile}bis failed"
17194
17195         # stop MDT to stop GC-thread, should be done in back-ground as it will
17196         # block waiting for the thread to be released and exit
17197         declare -A stop_pids
17198         for i in $(seq $MDSCOUNT); do
17199                 stop mds$i &
17200                 stop_pids[mds$i]=$!
17201         done
17202
17203         for i in $(mdts_nodes); do
17204                 local facet
17205                 local nb=0
17206                 local facets=$(facets_up_on_host $i)
17207
17208                 for facet in ${facets//,/ }; do
17209                         if [[ $facet == mds* ]]; then
17210                                 nb=$((nb + 1))
17211                         fi
17212                 done
17213                 # ensure each MDS's gc threads are still present and all in "R"
17214                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17215                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17216                         error "$i: expected $nb GC-thread"
17217                 wait_update $i \
17218                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17219                         "R" 20 ||
17220                         error "$i: GC-thread not found in R-state"
17221                 # check umounts of each MDT on MDS have reached kthread_stop()
17222                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17223                         error "$i: expected $nb umount"
17224                 wait_update $i \
17225                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17226                         error "$i: umount not found in D-state"
17227         done
17228
17229         # release all GC-threads
17230         do_nodes $mdts $LCTL set_param fail_loc=0
17231
17232         # wait for MDT stop to complete
17233         for i in $(seq $MDSCOUNT); do
17234                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17235         done
17236
17237         # XXX
17238         # may try to check if any orphan changelog records are present
17239         # via ldiskfs/zfs and llog_reader...
17240
17241         # re-start/mount MDTs
17242         for i in $(seq $MDSCOUNT); do
17243                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17244                         error "Fail to start mds$i"
17245         done
17246
17247         local first_rec
17248         for i in $(seq $MDSCOUNT); do
17249                 # check cl_user1 still registered
17250                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17251                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17252                 # check cl_user2 unregistered
17253                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17254                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17255
17256                 # check changelogs are present and starting at $user_rec1 + 1
17257                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17258                 [ -n "$user_rec1" ] ||
17259                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17260                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17261                             awk '{ print $1; exit; }')
17262
17263                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17264                 [ $((user_rec1 + 1)) == $first_rec ] ||
17265                         error "mds$i: first index should be $user_rec1 + 1, " \
17266                               "but is $first_rec"
17267         done
17268 }
17269 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17270               "during mount"
17271
17272 test_160i() {
17273
17274         local mdts=$(comma_list $(mdts_nodes))
17275
17276         changelog_register || error "first changelog_register failed"
17277
17278         # generate some changelog records to accumulate on each MDT
17279         # use all_char because created files should be evenly distributed
17280         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17281                 error "test_mkdir $tdir failed"
17282         for ((i = 0; i < MDSCOUNT; i++)); do
17283                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17284                         error "create $DIR/$tdir/d$i.1 failed"
17285         done
17286
17287         # check changelogs have been generated
17288         local nbcl=$(changelog_dump | wc -l)
17289         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17290
17291         # simulate race between register and unregister
17292         # XXX as fail_loc is set per-MDS, with DNE configs the race
17293         # simulation will only occur for one MDT per MDS and for the
17294         # others the normal race scenario will take place
17295         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17296         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17297         do_nodes $mdts $LCTL set_param fail_val=1
17298
17299         # unregister 1st user
17300         changelog_deregister &
17301         local pid1=$!
17302         # wait some time for deregister work to reach race rdv
17303         sleep 2
17304         # register 2nd user
17305         changelog_register || error "2nd user register failed"
17306
17307         wait $pid1 || error "1st user deregister failed"
17308
17309         local i
17310         local last_rec
17311         declare -A LAST_REC
17312         for i in $(seq $MDSCOUNT); do
17313                 if changelog_users mds$i | grep "^cl"; then
17314                         # make sure new records are added with one user present
17315                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17316                                           awk '/^current.index:/ { print $NF }')
17317                 else
17318                         error "mds$i has no user registered"
17319                 fi
17320         done
17321
17322         # generate more changelog records to accumulate on each MDT
17323         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17324                 error "create $DIR/$tdir/${tfile}bis failed"
17325
17326         for i in $(seq $MDSCOUNT); do
17327                 last_rec=$(changelog_users $SINGLEMDS |
17328                            awk '/^current.index:/ { print $NF }')
17329                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17330                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17331                         error "changelogs are off on mds$i"
17332         done
17333 }
17334 run_test 160i "changelog user register/unregister race"
17335
17336 test_160j() {
17337         remote_mds_nodsh && skip "remote MDS with nodsh"
17338         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17339                 skip "Need MDS version at least 2.12.56"
17340
17341         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17342         stack_trap "umount $MOUNT2" EXIT
17343
17344         changelog_register || error "first changelog_register failed"
17345         stack_trap "changelog_deregister" EXIT
17346
17347         # generate some changelog
17348         # use all_char because created files should be evenly distributed
17349         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17350                 error "mkdir $tdir failed"
17351         for ((i = 0; i < MDSCOUNT; i++)); do
17352                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17353                         error "create $DIR/$tdir/d$i.1 failed"
17354         done
17355
17356         # open the changelog device
17357         exec 3>/dev/changelog-$FSNAME-MDT0000
17358         stack_trap "exec 3>&-" EXIT
17359         exec 4</dev/changelog-$FSNAME-MDT0000
17360         stack_trap "exec 4<&-" EXIT
17361
17362         # umount the first lustre mount
17363         umount $MOUNT
17364         stack_trap "mount_client $MOUNT" EXIT
17365
17366         # read changelog, which may or may not fail, but should not crash
17367         cat <&4 >/dev/null
17368
17369         # clear changelog
17370         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17371         changelog_users $SINGLEMDS | grep -q $cl_user ||
17372                 error "User $cl_user not found in changelog_users"
17373
17374         printf 'clear:'$cl_user':0' >&3
17375 }
17376 run_test 160j "client can be umounted while its chanangelog is being used"
17377
17378 test_160k() {
17379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17380         remote_mds_nodsh && skip "remote MDS with nodsh"
17381
17382         mkdir -p $DIR/$tdir/1/1
17383
17384         changelog_register || error "changelog_register failed"
17385         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17386
17387         changelog_users $SINGLEMDS | grep -q $cl_user ||
17388                 error "User '$cl_user' not found in changelog_users"
17389 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17390         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17391         rmdir $DIR/$tdir/1/1 & sleep 1
17392         mkdir $DIR/$tdir/2
17393         touch $DIR/$tdir/2/2
17394         rm -rf $DIR/$tdir/2
17395
17396         wait
17397         sleep 4
17398
17399         changelog_dump | grep rmdir || error "rmdir not recorded"
17400 }
17401 run_test 160k "Verify that changelog records are not lost"
17402
17403 # Verifies that a file passed as a parameter has recently had an operation
17404 # performed on it that has generated an MTIME changelog which contains the
17405 # correct parent FID. As files might reside on a different MDT from the
17406 # parent directory in DNE configurations, the FIDs are translated to paths
17407 # before being compared, which should be identical
17408 compare_mtime_changelog() {
17409         local file="${1}"
17410         local mdtidx
17411         local mtime
17412         local cl_fid
17413         local pdir
17414         local dir
17415
17416         mdtidx=$($LFS getstripe --mdt-index $file)
17417         mdtidx=$(printf "%04x" $mdtidx)
17418
17419         # Obtain the parent FID from the MTIME changelog
17420         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17421         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17422
17423         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17424         [ -z "$cl_fid" ] && error "parent FID not present"
17425
17426         # Verify that the path for the parent FID is the same as the path for
17427         # the test directory
17428         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17429
17430         dir=$(dirname $1)
17431
17432         [[ "${pdir%/}" == "$dir" ]] ||
17433                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17434 }
17435
17436 test_160l() {
17437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17438
17439         remote_mds_nodsh && skip "remote MDS with nodsh"
17440         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17441                 skip "Need MDS version at least 2.13.55"
17442
17443         local cl_user
17444
17445         changelog_register || error "changelog_register failed"
17446         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17447
17448         changelog_users $SINGLEMDS | grep -q $cl_user ||
17449                 error "User '$cl_user' not found in changelog_users"
17450
17451         # Clear some types so that MTIME changelogs are generated
17452         changelog_chmask "-CREAT"
17453         changelog_chmask "-CLOSE"
17454
17455         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17456
17457         # Test CL_MTIME during setattr
17458         touch $DIR/$tdir/$tfile
17459         compare_mtime_changelog $DIR/$tdir/$tfile
17460
17461         # Test CL_MTIME during close
17462         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17463         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17464 }
17465 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17466
17467 test_160m() {
17468         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17469         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17470                 skip "Need MDS version at least 2.14.51"
17471         local cl_users
17472         local cl_user1
17473         local cl_user2
17474         local pid1
17475
17476         # Create a user
17477         changelog_register || error "first changelog_register failed"
17478         changelog_register || error "second changelog_register failed"
17479
17480         cl_users=(${CL_USERS[mds1]})
17481         cl_user1="${cl_users[0]}"
17482         cl_user2="${cl_users[1]}"
17483         # generate some changelog records to accumulate on MDT0
17484         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17485         createmany -m $DIR/$tdir/$tfile 50 ||
17486                 error "create $DIR/$tdir/$tfile failed"
17487         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17488         rm -f $DIR/$tdir
17489
17490         # check changelogs have been generated
17491         local nbcl=$(changelog_dump | wc -l)
17492         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17493
17494 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17495         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17496
17497         __changelog_clear mds1 $cl_user1 +10
17498         __changelog_clear mds1 $cl_user2 0 &
17499         pid1=$!
17500         sleep 2
17501         __changelog_clear mds1 $cl_user1 0 ||
17502                 error "fail to cancel record for $cl_user1"
17503         wait $pid1
17504         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17505 }
17506 run_test 160m "Changelog clear race"
17507
17508 test_160n() {
17509         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17510         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17511                 skip "Need MDS version at least 2.14.51"
17512         local cl_users
17513         local cl_user1
17514         local cl_user2
17515         local pid1
17516         local first_rec
17517         local last_rec=0
17518
17519         # Create a user
17520         changelog_register || error "first changelog_register failed"
17521
17522         cl_users=(${CL_USERS[mds1]})
17523         cl_user1="${cl_users[0]}"
17524
17525         # generate some changelog records to accumulate on MDT0
17526         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17527         first_rec=$(changelog_users $SINGLEMDS |
17528                         awk '/^current.index:/ { print $NF }')
17529         while (( last_rec < (( first_rec + 65000)) )); do
17530                 createmany -m $DIR/$tdir/$tfile 10000 ||
17531                         error "create $DIR/$tdir/$tfile failed"
17532
17533                 for i in $(seq 0 10000); do
17534                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17535                                 > /dev/null
17536                 done
17537
17538                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17539                         error "unlinkmany failed unlink"
17540                 last_rec=$(changelog_users $SINGLEMDS |
17541                         awk '/^current.index:/ { print $NF }')
17542                 echo last record $last_rec
17543                 (( last_rec == 0 )) && error "no changelog found"
17544         done
17545
17546 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17547         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17548
17549         __changelog_clear mds1 $cl_user1 0 &
17550         pid1=$!
17551         sleep 2
17552         __changelog_clear mds1 $cl_user1 0 ||
17553                 error "fail to cancel record for $cl_user1"
17554         wait $pid1
17555         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17556 }
17557 run_test 160n "Changelog destroy race"
17558
17559 test_160o() {
17560         local mdt="$(facet_svc $SINGLEMDS)"
17561
17562         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17563         remote_mds_nodsh && skip "remote MDS with nodsh"
17564         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17565                 skip "Need MDS version at least 2.14.52"
17566
17567         changelog_register --user test_160o -m unlnk+close+open ||
17568                 error "changelog_register failed"
17569
17570         do_facet $SINGLEMDS $LCTL --device $mdt \
17571                                 changelog_register -u "Tt3_-#" &&
17572                 error "bad symbols in name should fail"
17573
17574         do_facet $SINGLEMDS $LCTL --device $mdt \
17575                                 changelog_register -u test_160o &&
17576                 error "the same name registration should fail"
17577
17578         do_facet $SINGLEMDS $LCTL --device $mdt \
17579                         changelog_register -u test_160toolongname &&
17580                 error "too long name registration should fail"
17581
17582         changelog_chmask "MARK+HSM"
17583         lctl get_param mdd.*.changelog*mask
17584         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17585         changelog_users $SINGLEMDS | grep -q $cl_user ||
17586                 error "User $cl_user not found in changelog_users"
17587         #verify username
17588         echo $cl_user | grep -q test_160o ||
17589                 error "User $cl_user has no specific name 'test160o'"
17590
17591         # change something
17592         changelog_clear 0 || error "changelog_clear failed"
17593         # generate some changelog records to accumulate on MDT0
17594         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17595         touch $DIR/$tdir/$tfile                 # open 1
17596
17597         OPENS=$(changelog_dump | grep -c "OPEN")
17598         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17599
17600         # must be no MKDIR it wasn't set as user mask
17601         MKDIR=$(changelog_dump | grep -c "MKDIR")
17602         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17603
17604         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17605                                 mdd.$mdt.changelog_current_mask -n)
17606         # register maskless user
17607         changelog_register || error "changelog_register failed"
17608         # effective mask should be not changed because it is not minimal
17609         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17610                                 mdd.$mdt.changelog_current_mask -n)
17611         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17612         # set server mask to minimal value
17613         changelog_chmask "MARK"
17614         # check effective mask again, should be treated as DEFMASK now
17615         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17616                                 mdd.$mdt.changelog_current_mask -n)
17617         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17618
17619         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17620                 # set server mask back to some value
17621                 changelog_chmask "CLOSE,UNLNK"
17622                 # check effective mask again, should not remain as DEFMASK
17623                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17624                                 mdd.$mdt.changelog_current_mask -n)
17625                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17626         fi
17627
17628         do_facet $SINGLEMDS $LCTL --device $mdt \
17629                                 changelog_deregister -u test_160o ||
17630                 error "cannot deregister by name"
17631 }
17632 run_test 160o "changelog user name and mask"
17633
17634 test_160p() {
17635         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17636         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17637                 skip "Need MDS version at least 2.14.51"
17638         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17639         local cl_users
17640         local cl_user1
17641         local entry_count
17642
17643         # Create a user
17644         changelog_register || error "first changelog_register failed"
17645
17646         cl_users=(${CL_USERS[mds1]})
17647         cl_user1="${cl_users[0]}"
17648
17649         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17650         createmany -m $DIR/$tdir/$tfile 50 ||
17651                 error "create $DIR/$tdir/$tfile failed"
17652         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17653         rm -rf $DIR/$tdir
17654
17655         # check changelogs have been generated
17656         entry_count=$(changelog_dump | wc -l)
17657         ((entry_count != 0)) || error "no changelog entries found"
17658
17659         # remove changelog_users and check that orphan entries are removed
17660         stop mds1
17661         local dev=$(mdsdevname 1)
17662         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17663         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17664         entry_count=$(changelog_dump | wc -l)
17665         ((entry_count == 0)) ||
17666                 error "found $entry_count changelog entries, expected none"
17667 }
17668 run_test 160p "Changelog orphan cleanup with no users"
17669
17670 test_160q() {
17671         local mdt="$(facet_svc $SINGLEMDS)"
17672         local clu
17673
17674         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17675         remote_mds_nodsh && skip "remote MDS with nodsh"
17676         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17677                 skip "Need MDS version at least 2.14.54"
17678
17679         # set server mask to minimal value like server init does
17680         changelog_chmask "MARK"
17681         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17682                 error "changelog_register failed"
17683         # check effective mask again, should be treated as DEFMASK now
17684         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17685                                 mdd.$mdt.changelog_current_mask -n)
17686         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17687                 error "changelog_deregister failed"
17688         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17689 }
17690 run_test 160q "changelog effective mask is DEFMASK if not set"
17691
17692 test_160s() {
17693         remote_mds_nodsh && skip "remote MDS with nodsh"
17694         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17695                 skip "Need MDS version at least 2.14.55"
17696
17697         local mdts=$(comma_list $(mdts_nodes))
17698
17699         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17700         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17701                                        fail_val=$((24 * 3600 * 10))
17702
17703         # Create a user which is 10 days old
17704         changelog_register || error "first changelog_register failed"
17705         local cl_users
17706         declare -A cl_user1
17707         local i
17708
17709         # generate some changelog records to accumulate on each MDT
17710         # use all_char because created files should be evenly distributed
17711         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17712                 error "test_mkdir $tdir failed"
17713         for ((i = 0; i < MDSCOUNT; i++)); do
17714                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17715                         error "create $DIR/$tdir/d$i.1 failed"
17716         done
17717
17718         # check changelogs have been generated
17719         local nbcl=$(changelog_dump | wc -l)
17720         (( nbcl > 0 )) || error "no changelogs found"
17721
17722         # reduce the max_idle_indexes value to make sure we exceed it
17723         for param in "changelog_max_idle_indexes=2097446912" \
17724                      "changelog_max_idle_time=2592000" \
17725                      "changelog_gc=1" \
17726                      "changelog_min_gc_interval=2"; do
17727                 local MDT0=$(facet_svc $SINGLEMDS)
17728                 local var="${param%=*}"
17729                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17730
17731                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17732                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17733                         error "unable to set mdd.*.$param"
17734         done
17735
17736         local start=$SECONDS
17737         for i in $(seq $MDSCOUNT); do
17738                 cl_users=(${CL_USERS[mds$i]})
17739                 cl_user1[mds$i]="${cl_users[0]}"
17740
17741                 [[ -n "${cl_user1[mds$i]}" ]] ||
17742                         error "mds$i: no user registered"
17743         done
17744
17745         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17746         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17747
17748         # ensure we are past the previous changelog_min_gc_interval set above
17749         local sleep2=$((start + 2 - SECONDS))
17750         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17751
17752         # Generate one more changelog to trigger GC
17753         for ((i = 0; i < MDSCOUNT; i++)); do
17754                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17755                         error "create $DIR/$tdir/d$i.3 failed"
17756         done
17757
17758         # ensure gc thread is done
17759         for node in $(mdts_nodes); do
17760                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17761                         error "$node: GC-thread not done"
17762         done
17763
17764         do_nodes $mdts $LCTL set_param fail_loc=0
17765
17766         for (( i = 1; i <= MDSCOUNT; i++ )); do
17767                 # check cl_user1 is purged
17768                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17769                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17770         done
17771         return 0
17772 }
17773 run_test 160s "changelog garbage collect on idle records * time"
17774
17775 test_160t() {
17776         remote_mds_nodsh && skip "remote MDS with nodsh"
17777         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17778                 skip "Need MDS version at least 2.15.50"
17779
17780         local MDT0=$(facet_svc $SINGLEMDS)
17781         local cl_users
17782         local cl_user1
17783         local cl_user2
17784         local start
17785
17786         changelog_register --user user1 -m all ||
17787                 error "user1 failed to register"
17788
17789         mkdir_on_mdt0 $DIR/$tdir
17790         # create default overstripe to maximize changelog size
17791         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17792         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17793         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17794
17795         # user2 consumes less records so less space
17796         changelog_register --user user2 || error "user2 failed to register"
17797         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17798         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17799
17800         # check changelogs have been generated
17801         local nbcl=$(changelog_dump | wc -l)
17802         (( nbcl > 0 )) || error "no changelogs found"
17803
17804         # reduce the changelog_min_gc_interval to force check
17805         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17806                 local var="${param%=*}"
17807                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17808
17809                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17810                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17811                         error "unable to set mdd.*.$param"
17812         done
17813
17814         start=$SECONDS
17815         cl_users=(${CL_USERS[mds1]})
17816         cl_user1="${cl_users[0]}"
17817         cl_user2="${cl_users[1]}"
17818
17819         [[ -n $cl_user1 ]] ||
17820                 error "mds1: user #1 isn't registered"
17821         [[ -n $cl_user2 ]] ||
17822                 error "mds1: user #2 isn't registered"
17823
17824         # ensure we are past the previous changelog_min_gc_interval set above
17825         local sleep2=$((start + 2 - SECONDS))
17826         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17827
17828         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17829         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17830                         fail_val=$(((llog_size1 + llog_size2) / 2))
17831
17832         # Generate more changelog to trigger GC
17833         createmany -o $DIR/$tdir/u3_ 4 ||
17834                 error "create failed for more files"
17835
17836         # ensure gc thread is done
17837         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17838                 error "mds1: GC-thread not done"
17839
17840         do_facet mds1 $LCTL set_param fail_loc=0
17841
17842         # check cl_user1 is purged
17843         changelog_users mds1 | grep -q "$cl_user1" &&
17844                 error "User $cl_user1 is registered"
17845         # check cl_user2 is not purged
17846         changelog_users mds1 | grep -q "$cl_user2" ||
17847                 error "User $cl_user2 is not registered"
17848 }
17849 run_test 160t "changelog garbage collect on lack of space"
17850
17851 test_161a() {
17852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17853
17854         test_mkdir -c1 $DIR/$tdir
17855         cp /etc/hosts $DIR/$tdir/$tfile
17856         test_mkdir -c1 $DIR/$tdir/foo1
17857         test_mkdir -c1 $DIR/$tdir/foo2
17858         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17859         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17860         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17861         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17862         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17863         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17864                 $LFS fid2path $DIR $FID
17865                 error "bad link ea"
17866         fi
17867         # middle
17868         rm $DIR/$tdir/foo2/zachary
17869         # last
17870         rm $DIR/$tdir/foo2/thor
17871         # first
17872         rm $DIR/$tdir/$tfile
17873         # rename
17874         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17875         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17876                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17877         rm $DIR/$tdir/foo2/maggie
17878
17879         # overflow the EA
17880         local longname=$tfile.avg_len_is_thirty_two_
17881         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17882                 error_noexit 'failed to unlink many hardlinks'" EXIT
17883         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/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 ]] || error "expected at least 60 links in link EA"
17888 }
17889 run_test 161a "link ea sanity"
17890
17891 test_161b() {
17892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17893         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17894
17895         local MDTIDX=1
17896         local remote_dir=$DIR/$tdir/remote_dir
17897
17898         mkdir -p $DIR/$tdir
17899         $LFS mkdir -i $MDTIDX $remote_dir ||
17900                 error "create remote directory failed"
17901
17902         cp /etc/hosts $remote_dir/$tfile
17903         mkdir -p $remote_dir/foo1
17904         mkdir -p $remote_dir/foo2
17905         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17906         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17907         ln $remote_dir/$tfile $remote_dir/foo1/luna
17908         ln $remote_dir/$tfile $remote_dir/foo2/thor
17909
17910         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17911                      tr -d ']')
17912         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17913                 $LFS fid2path $DIR $FID
17914                 error "bad link ea"
17915         fi
17916         # middle
17917         rm $remote_dir/foo2/zachary
17918         # last
17919         rm $remote_dir/foo2/thor
17920         # first
17921         rm $remote_dir/$tfile
17922         # rename
17923         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17924         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17925         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17926                 $LFS fid2path $DIR $FID
17927                 error "bad link rename"
17928         fi
17929         rm $remote_dir/foo2/maggie
17930
17931         # overflow the EA
17932         local longname=filename_avg_len_is_thirty_two_
17933         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17934                 error "failed to hardlink many files"
17935         links=$($LFS fid2path $DIR $FID | wc -l)
17936         echo -n "${links}/1000 links in link EA"
17937         [[ ${links} -gt 60 ]] ||
17938                 error "expected at least 60 links in link EA"
17939         unlinkmany $remote_dir/foo2/$longname 1000 ||
17940         error "failed to unlink many hardlinks"
17941 }
17942 run_test 161b "link ea sanity under remote directory"
17943
17944 test_161c() {
17945         remote_mds_nodsh && skip "remote MDS with nodsh"
17946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17947         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17948                 skip "Need MDS version at least 2.1.5"
17949
17950         # define CLF_RENAME_LAST 0x0001
17951         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17952         changelog_register || error "changelog_register failed"
17953
17954         rm -rf $DIR/$tdir
17955         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17956         touch $DIR/$tdir/foo_161c
17957         touch $DIR/$tdir/bar_161c
17958         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17959         changelog_dump | grep RENME | tail -n 5
17960         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17961         changelog_clear 0 || error "changelog_clear failed"
17962         if [ x$flags != "x0x1" ]; then
17963                 error "flag $flags is not 0x1"
17964         fi
17965
17966         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17967         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17968         touch $DIR/$tdir/foo_161c
17969         touch $DIR/$tdir/bar_161c
17970         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17971         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17972         changelog_dump | grep RENME | tail -n 5
17973         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17974         changelog_clear 0 || error "changelog_clear failed"
17975         if [ x$flags != "x0x0" ]; then
17976                 error "flag $flags is not 0x0"
17977         fi
17978         echo "rename overwrite a target having nlink > 1," \
17979                 "changelog record has flags of $flags"
17980
17981         # rename doesn't overwrite a target (changelog flag 0x0)
17982         touch $DIR/$tdir/foo_161c
17983         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17984         changelog_dump | grep RENME | tail -n 5
17985         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17986         changelog_clear 0 || error "changelog_clear failed"
17987         if [ x$flags != "x0x0" ]; then
17988                 error "flag $flags is not 0x0"
17989         fi
17990         echo "rename doesn't overwrite a target," \
17991                 "changelog record has flags of $flags"
17992
17993         # define CLF_UNLINK_LAST 0x0001
17994         # unlink a file having nlink = 1 (changelog flag 0x1)
17995         rm -f $DIR/$tdir/foo2_161c
17996         changelog_dump | grep UNLNK | tail -n 5
17997         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17998         changelog_clear 0 || error "changelog_clear failed"
17999         if [ x$flags != "x0x1" ]; then
18000                 error "flag $flags is not 0x1"
18001         fi
18002         echo "unlink a file having nlink = 1," \
18003                 "changelog record has flags of $flags"
18004
18005         # unlink a file having nlink > 1 (changelog flag 0x0)
18006         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18007         rm -f $DIR/$tdir/foobar_161c
18008         changelog_dump | grep UNLNK | tail -n 5
18009         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18010         changelog_clear 0 || error "changelog_clear failed"
18011         if [ x$flags != "x0x0" ]; then
18012                 error "flag $flags is not 0x0"
18013         fi
18014         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18015 }
18016 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18017
18018 test_161d() {
18019         remote_mds_nodsh && skip "remote MDS with nodsh"
18020         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18021
18022         local pid
18023         local fid
18024
18025         changelog_register || error "changelog_register failed"
18026
18027         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18028         # interfer with $MOUNT/.lustre/fid/ access
18029         mkdir $DIR/$tdir
18030         [[ $? -eq 0 ]] || error "mkdir failed"
18031
18032         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
18033         $LCTL set_param fail_loc=0x8000140c
18034         # 5s pause
18035         $LCTL set_param fail_val=5
18036
18037         # create file
18038         echo foofoo > $DIR/$tdir/$tfile &
18039         pid=$!
18040
18041         # wait for create to be delayed
18042         sleep 2
18043
18044         ps -p $pid
18045         [[ $? -eq 0 ]] || error "create should be blocked"
18046
18047         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18048         stack_trap "rm -f $tempfile"
18049         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18050         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18051         # some delay may occur during ChangeLog publishing and file read just
18052         # above, that could allow file write to happen finally
18053         [[ -s $tempfile ]] && echo "file should be empty"
18054
18055         $LCTL set_param fail_loc=0
18056
18057         wait $pid
18058         [[ $? -eq 0 ]] || error "create failed"
18059 }
18060 run_test 161d "create with concurrent .lustre/fid access"
18061
18062 check_path() {
18063         local expected="$1"
18064         shift
18065         local fid="$2"
18066
18067         local path
18068         path=$($LFS fid2path "$@")
18069         local rc=$?
18070
18071         if [ $rc -ne 0 ]; then
18072                 error "path looked up of '$expected' failed: rc=$rc"
18073         elif [ "$path" != "$expected" ]; then
18074                 error "path looked up '$path' instead of '$expected'"
18075         else
18076                 echo "FID '$fid' resolves to path '$path' as expected"
18077         fi
18078 }
18079
18080 test_162a() { # was test_162
18081         test_mkdir -p -c1 $DIR/$tdir/d2
18082         touch $DIR/$tdir/d2/$tfile
18083         touch $DIR/$tdir/d2/x1
18084         touch $DIR/$tdir/d2/x2
18085         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18086         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18087         # regular file
18088         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18089         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18090
18091         # softlink
18092         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18093         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18094         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18095
18096         # softlink to wrong file
18097         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18098         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18099         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18100
18101         # hardlink
18102         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18103         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18104         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18105         # fid2path dir/fsname should both work
18106         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18107         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18108
18109         # hardlink count: check that there are 2 links
18110         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18111         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18112
18113         # hardlink indexing: remove the first link
18114         rm $DIR/$tdir/d2/p/q/r/hlink
18115         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18116 }
18117 run_test 162a "path lookup sanity"
18118
18119 test_162b() {
18120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18122
18123         mkdir $DIR/$tdir
18124         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18125                                 error "create striped dir failed"
18126
18127         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18128                                         tail -n 1 | awk '{print $2}')
18129         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18130
18131         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18132         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18133
18134         # regular file
18135         for ((i=0;i<5;i++)); do
18136                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18137                         error "get fid for f$i failed"
18138                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18139
18140                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18141                         error "get fid for d$i failed"
18142                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18143         done
18144
18145         return 0
18146 }
18147 run_test 162b "striped directory path lookup sanity"
18148
18149 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18150 test_162c() {
18151         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18152                 skip "Need MDS version at least 2.7.51"
18153
18154         local lpath=$tdir.local
18155         local rpath=$tdir.remote
18156
18157         test_mkdir $DIR/$lpath
18158         test_mkdir $DIR/$rpath
18159
18160         for ((i = 0; i <= 101; i++)); do
18161                 lpath="$lpath/$i"
18162                 mkdir $DIR/$lpath
18163                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18164                         error "get fid for local directory $DIR/$lpath failed"
18165                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18166
18167                 rpath="$rpath/$i"
18168                 test_mkdir $DIR/$rpath
18169                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18170                         error "get fid for remote directory $DIR/$rpath failed"
18171                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18172         done
18173
18174         return 0
18175 }
18176 run_test 162c "fid2path works with paths 100 or more directories deep"
18177
18178 oalr_event_count() {
18179         local event="${1}"
18180         local trace="${2}"
18181
18182         awk -v name="${FSNAME}-OST0000" \
18183             -v event="${event}" \
18184             '$1 == "TRACE" && $2 == event && $3 == name' \
18185             "${trace}" |
18186         wc -l
18187 }
18188
18189 oalr_expect_event_count() {
18190         local event="${1}"
18191         local trace="${2}"
18192         local expect="${3}"
18193         local count
18194
18195         count=$(oalr_event_count "${event}" "${trace}")
18196         if ((count == expect)); then
18197                 return 0
18198         fi
18199
18200         error_noexit "${event} event count was '${count}', expected ${expect}"
18201         cat "${trace}" >&2
18202         exit 1
18203 }
18204
18205 cleanup_165() {
18206         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18207         stop ost1
18208         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18209 }
18210
18211 setup_165() {
18212         sync # Flush previous IOs so we can count log entries.
18213         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18214         stack_trap cleanup_165 EXIT
18215 }
18216
18217 test_165a() {
18218         local trace="/tmp/${tfile}.trace"
18219         local rc
18220         local count
18221
18222         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18223                 skip "OFD access log unsupported"
18224
18225         setup_165
18226         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18227         sleep 5
18228
18229         do_facet ost1 ofd_access_log_reader --list
18230         stop ost1
18231
18232         do_facet ost1 killall -TERM ofd_access_log_reader
18233         wait
18234         rc=$?
18235
18236         if ((rc != 0)); then
18237                 error "ofd_access_log_reader exited with rc = '${rc}'"
18238         fi
18239
18240         # Parse trace file for discovery events:
18241         oalr_expect_event_count alr_log_add "${trace}" 1
18242         oalr_expect_event_count alr_log_eof "${trace}" 1
18243         oalr_expect_event_count alr_log_free "${trace}" 1
18244 }
18245 run_test 165a "ofd access log discovery"
18246
18247 test_165b() {
18248         local trace="/tmp/${tfile}.trace"
18249         local file="${DIR}/${tfile}"
18250         local pfid1
18251         local pfid2
18252         local -a entry
18253         local rc
18254         local count
18255         local size
18256         local flags
18257
18258         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18259                 skip "OFD access log unsupported"
18260
18261         setup_165
18262         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18263         sleep 5
18264
18265         do_facet ost1 ofd_access_log_reader --list
18266
18267         lfs setstripe -c 1 -i 0 "${file}"
18268         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18269                 error "cannot create '${file}'"
18270
18271         sleep 5
18272         do_facet ost1 killall -TERM ofd_access_log_reader
18273         wait
18274         rc=$?
18275
18276         if ((rc != 0)); then
18277                 error "ofd_access_log_reader exited with rc = '${rc}'"
18278         fi
18279
18280         oalr_expect_event_count alr_log_entry "${trace}" 1
18281
18282         pfid1=$($LFS path2fid "${file}")
18283
18284         # 1     2             3   4    5     6   7    8    9     10
18285         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18286         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18287
18288         echo "entry = '${entry[*]}'" >&2
18289
18290         pfid2=${entry[4]}
18291         if [[ "${pfid1}" != "${pfid2}" ]]; then
18292                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18293         fi
18294
18295         size=${entry[8]}
18296         if ((size != 1048576)); then
18297                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18298         fi
18299
18300         flags=${entry[10]}
18301         if [[ "${flags}" != "w" ]]; then
18302                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18303         fi
18304
18305         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18306         sleep 5
18307
18308         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18309                 error "cannot read '${file}'"
18310         sleep 5
18311
18312         do_facet ost1 killall -TERM ofd_access_log_reader
18313         wait
18314         rc=$?
18315
18316         if ((rc != 0)); then
18317                 error "ofd_access_log_reader exited with rc = '${rc}'"
18318         fi
18319
18320         oalr_expect_event_count alr_log_entry "${trace}" 1
18321
18322         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18323         echo "entry = '${entry[*]}'" >&2
18324
18325         pfid2=${entry[4]}
18326         if [[ "${pfid1}" != "${pfid2}" ]]; then
18327                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18328         fi
18329
18330         size=${entry[8]}
18331         if ((size != 524288)); then
18332                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18333         fi
18334
18335         flags=${entry[10]}
18336         if [[ "${flags}" != "r" ]]; then
18337                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18338         fi
18339 }
18340 run_test 165b "ofd access log entries are produced and consumed"
18341
18342 test_165c() {
18343         local trace="/tmp/${tfile}.trace"
18344         local file="${DIR}/${tdir}/${tfile}"
18345
18346         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18347                 skip "OFD access log unsupported"
18348
18349         test_mkdir "${DIR}/${tdir}"
18350
18351         setup_165
18352         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18353         sleep 5
18354
18355         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18356
18357         # 4096 / 64 = 64. Create twice as many entries.
18358         for ((i = 0; i < 128; i++)); do
18359                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18360                         error "cannot create file"
18361         done
18362
18363         sync
18364
18365         do_facet ost1 killall -TERM ofd_access_log_reader
18366         wait
18367         rc=$?
18368         if ((rc != 0)); then
18369                 error "ofd_access_log_reader exited with rc = '${rc}'"
18370         fi
18371
18372         unlinkmany  "${file}-%d" 128
18373 }
18374 run_test 165c "full ofd access logs do not block IOs"
18375
18376 oal_get_read_count() {
18377         local stats="$1"
18378
18379         # STATS lustre-OST0001 alr_read_count 1
18380
18381         do_facet ost1 cat "${stats}" |
18382         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18383              END { print count; }'
18384 }
18385
18386 oal_expect_read_count() {
18387         local stats="$1"
18388         local count
18389         local expect="$2"
18390
18391         # Ask ofd_access_log_reader to write stats.
18392         do_facet ost1 killall -USR1 ofd_access_log_reader
18393
18394         # Allow some time for things to happen.
18395         sleep 1
18396
18397         count=$(oal_get_read_count "${stats}")
18398         if ((count == expect)); then
18399                 return 0
18400         fi
18401
18402         error_noexit "bad read count, got ${count}, expected ${expect}"
18403         do_facet ost1 cat "${stats}" >&2
18404         exit 1
18405 }
18406
18407 test_165d() {
18408         local stats="/tmp/${tfile}.stats"
18409         local file="${DIR}/${tdir}/${tfile}"
18410         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18411
18412         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18413                 skip "OFD access log unsupported"
18414
18415         test_mkdir "${DIR}/${tdir}"
18416
18417         setup_165
18418         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18419         sleep 5
18420
18421         lfs setstripe -c 1 -i 0 "${file}"
18422
18423         do_facet ost1 lctl set_param "${param}=rw"
18424         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18425                 error "cannot create '${file}'"
18426         oal_expect_read_count "${stats}" 1
18427
18428         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18429                 error "cannot read '${file}'"
18430         oal_expect_read_count "${stats}" 2
18431
18432         do_facet ost1 lctl set_param "${param}=r"
18433         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18434                 error "cannot create '${file}'"
18435         oal_expect_read_count "${stats}" 2
18436
18437         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18438                 error "cannot read '${file}'"
18439         oal_expect_read_count "${stats}" 3
18440
18441         do_facet ost1 lctl set_param "${param}=w"
18442         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18443                 error "cannot create '${file}'"
18444         oal_expect_read_count "${stats}" 4
18445
18446         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18447                 error "cannot read '${file}'"
18448         oal_expect_read_count "${stats}" 4
18449
18450         do_facet ost1 lctl set_param "${param}=0"
18451         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18452                 error "cannot create '${file}'"
18453         oal_expect_read_count "${stats}" 4
18454
18455         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18456                 error "cannot read '${file}'"
18457         oal_expect_read_count "${stats}" 4
18458
18459         do_facet ost1 killall -TERM ofd_access_log_reader
18460         wait
18461         rc=$?
18462         if ((rc != 0)); then
18463                 error "ofd_access_log_reader exited with rc = '${rc}'"
18464         fi
18465 }
18466 run_test 165d "ofd_access_log mask works"
18467
18468 test_165e() {
18469         local stats="/tmp/${tfile}.stats"
18470         local file0="${DIR}/${tdir}-0/${tfile}"
18471         local file1="${DIR}/${tdir}-1/${tfile}"
18472
18473         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18474                 skip "OFD access log unsupported"
18475
18476         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18477
18478         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18479         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18480
18481         lfs setstripe -c 1 -i 0 "${file0}"
18482         lfs setstripe -c 1 -i 0 "${file1}"
18483
18484         setup_165
18485         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18486         sleep 5
18487
18488         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18489                 error "cannot create '${file0}'"
18490         sync
18491         oal_expect_read_count "${stats}" 0
18492
18493         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18494                 error "cannot create '${file1}'"
18495         sync
18496         oal_expect_read_count "${stats}" 1
18497
18498         do_facet ost1 killall -TERM ofd_access_log_reader
18499         wait
18500         rc=$?
18501         if ((rc != 0)); then
18502                 error "ofd_access_log_reader exited with rc = '${rc}'"
18503         fi
18504 }
18505 run_test 165e "ofd_access_log MDT index filter works"
18506
18507 test_165f() {
18508         local trace="/tmp/${tfile}.trace"
18509         local rc
18510         local count
18511
18512         setup_165
18513         do_facet ost1 timeout 60 ofd_access_log_reader \
18514                 --exit-on-close --debug=- --trace=- > "${trace}" &
18515         sleep 5
18516         stop ost1
18517
18518         wait
18519         rc=$?
18520
18521         if ((rc != 0)); then
18522                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18523                 cat "${trace}"
18524                 exit 1
18525         fi
18526 }
18527 run_test 165f "ofd_access_log_reader --exit-on-close works"
18528
18529 test_169() {
18530         # do directio so as not to populate the page cache
18531         log "creating a 10 Mb file"
18532         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18533                 error "multiop failed while creating a file"
18534         log "starting reads"
18535         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18536         log "truncating the file"
18537         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18538                 error "multiop failed while truncating the file"
18539         log "killing dd"
18540         kill %+ || true # reads might have finished
18541         echo "wait until dd is finished"
18542         wait
18543         log "removing the temporary file"
18544         rm -rf $DIR/$tfile || error "tmp file removal failed"
18545 }
18546 run_test 169 "parallel read and truncate should not deadlock"
18547
18548 test_170() {
18549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18550
18551         $LCTL clear     # bug 18514
18552         $LCTL debug_daemon start $TMP/${tfile}_log_good
18553         touch $DIR/$tfile
18554         $LCTL debug_daemon stop
18555         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18556                 error "sed failed to read log_good"
18557
18558         $LCTL debug_daemon start $TMP/${tfile}_log_good
18559         rm -rf $DIR/$tfile
18560         $LCTL debug_daemon stop
18561
18562         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18563                error "lctl df log_bad failed"
18564
18565         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18566         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18567
18568         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18569         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18570
18571         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18572                 error "bad_line good_line1 good_line2 are empty"
18573
18574         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18575         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18576         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18577
18578         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18579         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18580         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18581
18582         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18583                 error "bad_line_new good_line_new are empty"
18584
18585         local expected_good=$((good_line1 + good_line2*2))
18586
18587         rm -f $TMP/${tfile}*
18588         # LU-231, short malformed line may not be counted into bad lines
18589         if [ $bad_line -ne $bad_line_new ] &&
18590                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18591                 error "expected $bad_line bad lines, but got $bad_line_new"
18592                 return 1
18593         fi
18594
18595         if [ $expected_good -ne $good_line_new ]; then
18596                 error "expected $expected_good good lines, but got $good_line_new"
18597                 return 2
18598         fi
18599         true
18600 }
18601 run_test 170 "test lctl df to handle corrupted log ====================="
18602
18603 test_171() { # bug20592
18604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18605
18606         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18607         $LCTL set_param fail_loc=0x50e
18608         $LCTL set_param fail_val=3000
18609         multiop_bg_pause $DIR/$tfile O_s || true
18610         local MULTIPID=$!
18611         kill -USR1 $MULTIPID
18612         # cause log dump
18613         sleep 3
18614         wait $MULTIPID
18615         if dmesg | grep "recursive fault"; then
18616                 error "caught a recursive fault"
18617         fi
18618         $LCTL set_param fail_loc=0
18619         true
18620 }
18621 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18622
18623 test_172() {
18624
18625         #define OBD_FAIL_OBD_CLEANUP  0x60e
18626         $LCTL set_param fail_loc=0x60e
18627         umount $MOUNT || error "umount $MOUNT failed"
18628         stack_trap "mount_client $MOUNT"
18629
18630         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18631                 error "no client OBDs are remained"
18632
18633         $LCTL dl | while read devno state type name foo; do
18634                 case $type in
18635                 lov|osc|lmv|mdc)
18636                         $LCTL --device $name cleanup
18637                         $LCTL --device $name detach
18638                         ;;
18639                 *)
18640                         # skip server devices
18641                         ;;
18642                 esac
18643         done
18644
18645         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18646                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18647                 error "some client OBDs are still remained"
18648         fi
18649
18650 }
18651 run_test 172 "manual device removal with lctl cleanup/detach ======"
18652
18653 # it would be good to share it with obdfilter-survey/iokit-libecho code
18654 setup_obdecho_osc () {
18655         local rc=0
18656         local ost_nid=$1
18657         local obdfilter_name=$2
18658         echo "Creating new osc for $obdfilter_name on $ost_nid"
18659         # make sure we can find loopback nid
18660         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18661
18662         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18663                            ${obdfilter_name}_osc_UUID || rc=2; }
18664         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18665                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18666         return $rc
18667 }
18668
18669 cleanup_obdecho_osc () {
18670         local obdfilter_name=$1
18671         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18672         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18673         return 0
18674 }
18675
18676 obdecho_test() {
18677         local OBD=$1
18678         local node=$2
18679         local pages=${3:-64}
18680         local rc=0
18681         local id
18682
18683         local count=10
18684         local obd_size=$(get_obd_size $node $OBD)
18685         local page_size=$(get_page_size $node)
18686         if [[ -n "$obd_size" ]]; then
18687                 local new_count=$((obd_size / (pages * page_size / 1024)))
18688                 [[ $new_count -ge $count ]] || count=$new_count
18689         fi
18690
18691         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18692         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18693                            rc=2; }
18694         if [ $rc -eq 0 ]; then
18695             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18696             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18697         fi
18698         echo "New object id is $id"
18699         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18700                            rc=4; }
18701         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18702                            "test_brw $count w v $pages $id" || rc=4; }
18703         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18704                            rc=4; }
18705         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18706                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18707         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18708                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18709         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18710         return $rc
18711 }
18712
18713 test_180a() {
18714         skip "obdecho on osc is no longer supported"
18715 }
18716 run_test 180a "test obdecho on osc"
18717
18718 test_180b() {
18719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18720         remote_ost_nodsh && skip "remote OST with nodsh"
18721
18722         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18723                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18724                 error "failed to load module obdecho"
18725
18726         local target=$(do_facet ost1 $LCTL dl |
18727                        awk '/obdfilter/ { print $4; exit; }')
18728
18729         if [ -n "$target" ]; then
18730                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18731         else
18732                 do_facet ost1 $LCTL dl
18733                 error "there is no obdfilter target on ost1"
18734         fi
18735 }
18736 run_test 180b "test obdecho directly on obdfilter"
18737
18738 test_180c() { # LU-2598
18739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18740         remote_ost_nodsh && skip "remote OST with nodsh"
18741         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18742                 skip "Need MDS version at least 2.4.0"
18743
18744         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18745                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18746                 error "failed to load module obdecho"
18747
18748         local target=$(do_facet ost1 $LCTL dl |
18749                        awk '/obdfilter/ { print $4; exit; }')
18750
18751         if [ -n "$target" ]; then
18752                 local pages=16384 # 64MB bulk I/O RPC size
18753
18754                 obdecho_test "$target" ost1 "$pages" ||
18755                         error "obdecho_test with pages=$pages failed with $?"
18756         else
18757                 do_facet ost1 $LCTL dl
18758                 error "there is no obdfilter target on ost1"
18759         fi
18760 }
18761 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18762
18763 test_181() { # bug 22177
18764         test_mkdir $DIR/$tdir
18765         # create enough files to index the directory
18766         createmany -o $DIR/$tdir/foobar 4000
18767         # print attributes for debug purpose
18768         lsattr -d .
18769         # open dir
18770         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18771         MULTIPID=$!
18772         # remove the files & current working dir
18773         unlinkmany $DIR/$tdir/foobar 4000
18774         rmdir $DIR/$tdir
18775         kill -USR1 $MULTIPID
18776         wait $MULTIPID
18777         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18778         return 0
18779 }
18780 run_test 181 "Test open-unlinked dir ========================"
18781
18782 test_182a() {
18783         local fcount=1000
18784         local tcount=10
18785
18786         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18787
18788         $LCTL set_param mdc.*.rpc_stats=clear
18789
18790         for (( i = 0; i < $tcount; i++ )) ; do
18791                 mkdir $DIR/$tdir/$i
18792         done
18793
18794         for (( i = 0; i < $tcount; i++ )) ; do
18795                 createmany -o $DIR/$tdir/$i/f- $fcount &
18796         done
18797         wait
18798
18799         for (( i = 0; i < $tcount; i++ )) ; do
18800                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18801         done
18802         wait
18803
18804         $LCTL get_param mdc.*.rpc_stats
18805
18806         rm -rf $DIR/$tdir
18807 }
18808 run_test 182a "Test parallel modify metadata operations from mdc"
18809
18810 test_182b() {
18811         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18812         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18813         local dcount=1000
18814         local tcount=10
18815         local stime
18816         local etime
18817         local delta
18818
18819         do_facet mds1 $LCTL list_param \
18820                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18821                 skip "MDS lacks parallel RPC handling"
18822
18823         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18824
18825         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18826                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18827
18828         stime=$(date +%s)
18829         createmany -i 0 -d $DIR/$tdir/t- $tcount
18830
18831         for (( i = 0; i < $tcount; i++ )) ; do
18832                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18833         done
18834         wait
18835         etime=$(date +%s)
18836         delta=$((etime - stime))
18837         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18838
18839         stime=$(date +%s)
18840         for (( i = 0; i < $tcount; i++ )) ; do
18841                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18842         done
18843         wait
18844         etime=$(date +%s)
18845         delta=$((etime - stime))
18846         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18847
18848         rm -rf $DIR/$tdir
18849
18850         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18851
18852         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18853
18854         stime=$(date +%s)
18855         createmany -i 0 -d $DIR/$tdir/t- $tcount
18856
18857         for (( i = 0; i < $tcount; i++ )) ; do
18858                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18859         done
18860         wait
18861         etime=$(date +%s)
18862         delta=$((etime - stime))
18863         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18864
18865         stime=$(date +%s)
18866         for (( i = 0; i < $tcount; i++ )) ; do
18867                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18868         done
18869         wait
18870         etime=$(date +%s)
18871         delta=$((etime - stime))
18872         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18873
18874         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18875 }
18876 run_test 182b "Test parallel modify metadata operations from osp"
18877
18878 test_183() { # LU-2275
18879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18880         remote_mds_nodsh && skip "remote MDS with nodsh"
18881         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18882                 skip "Need MDS version at least 2.3.56"
18883
18884         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18885         echo aaa > $DIR/$tdir/$tfile
18886
18887 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18888         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18889
18890         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18891         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18892
18893         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18894
18895         # Flush negative dentry cache
18896         touch $DIR/$tdir/$tfile
18897
18898         # We are not checking for any leaked references here, they'll
18899         # become evident next time we do cleanup with module unload.
18900         rm -rf $DIR/$tdir
18901 }
18902 run_test 183 "No crash or request leak in case of strange dispositions ========"
18903
18904 # test suite 184 is for LU-2016, LU-2017
18905 test_184a() {
18906         check_swap_layouts_support
18907
18908         dir0=$DIR/$tdir/$testnum
18909         test_mkdir -p -c1 $dir0
18910         ref1=/etc/passwd
18911         ref2=/etc/group
18912         file1=$dir0/f1
18913         file2=$dir0/f2
18914         $LFS setstripe -c1 $file1
18915         cp $ref1 $file1
18916         $LFS setstripe -c2 $file2
18917         cp $ref2 $file2
18918         gen1=$($LFS getstripe -g $file1)
18919         gen2=$($LFS getstripe -g $file2)
18920
18921         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18922         gen=$($LFS getstripe -g $file1)
18923         [[ $gen1 != $gen ]] ||
18924                 error "Layout generation on $file1 does not change"
18925         gen=$($LFS getstripe -g $file2)
18926         [[ $gen2 != $gen ]] ||
18927                 error "Layout generation on $file2 does not change"
18928
18929         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18930         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18931
18932         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18933 }
18934 run_test 184a "Basic layout swap"
18935
18936 test_184b() {
18937         check_swap_layouts_support
18938
18939         dir0=$DIR/$tdir/$testnum
18940         mkdir -p $dir0 || error "creating dir $dir0"
18941         file1=$dir0/f1
18942         file2=$dir0/f2
18943         file3=$dir0/f3
18944         dir1=$dir0/d1
18945         dir2=$dir0/d2
18946         mkdir $dir1 $dir2
18947         $LFS setstripe -c1 $file1
18948         $LFS setstripe -c2 $file2
18949         $LFS setstripe -c1 $file3
18950         chown $RUNAS_ID $file3
18951         gen1=$($LFS getstripe -g $file1)
18952         gen2=$($LFS getstripe -g $file2)
18953
18954         $LFS swap_layouts $dir1 $dir2 &&
18955                 error "swap of directories layouts should fail"
18956         $LFS swap_layouts $dir1 $file1 &&
18957                 error "swap of directory and file layouts should fail"
18958         $RUNAS $LFS swap_layouts $file1 $file2 &&
18959                 error "swap of file we cannot write should fail"
18960         $LFS swap_layouts $file1 $file3 &&
18961                 error "swap of file with different owner should fail"
18962         /bin/true # to clear error code
18963 }
18964 run_test 184b "Forbidden layout swap (will generate errors)"
18965
18966 test_184c() {
18967         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18968         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18969         check_swap_layouts_support
18970         check_swap_layout_no_dom $DIR
18971
18972         local dir0=$DIR/$tdir/$testnum
18973         mkdir -p $dir0 || error "creating dir $dir0"
18974
18975         local ref1=$dir0/ref1
18976         local ref2=$dir0/ref2
18977         local file1=$dir0/file1
18978         local file2=$dir0/file2
18979         # create a file large enough for the concurrent test
18980         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18981         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18982         echo "ref file size: ref1($(stat -c %s $ref1))," \
18983              "ref2($(stat -c %s $ref2))"
18984
18985         cp $ref2 $file2
18986         dd if=$ref1 of=$file1 bs=16k &
18987         local DD_PID=$!
18988
18989         # Make sure dd starts to copy file, but wait at most 5 seconds
18990         local loops=0
18991         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18992
18993         $LFS swap_layouts $file1 $file2
18994         local rc=$?
18995         wait $DD_PID
18996         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18997         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18998
18999         # how many bytes copied before swapping layout
19000         local copied=$(stat -c %s $file2)
19001         local remaining=$(stat -c %s $ref1)
19002         remaining=$((remaining - copied))
19003         echo "Copied $copied bytes before swapping layout..."
19004
19005         cmp -n $copied $file1 $ref2 | grep differ &&
19006                 error "Content mismatch [0, $copied) of ref2 and file1"
19007         cmp -n $copied $file2 $ref1 ||
19008                 error "Content mismatch [0, $copied) of ref1 and file2"
19009         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19010                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19011
19012         # clean up
19013         rm -f $ref1 $ref2 $file1 $file2
19014 }
19015 run_test 184c "Concurrent write and layout swap"
19016
19017 test_184d() {
19018         check_swap_layouts_support
19019         check_swap_layout_no_dom $DIR
19020         [ -z "$(which getfattr 2>/dev/null)" ] &&
19021                 skip_env "no getfattr command"
19022
19023         local file1=$DIR/$tdir/$tfile-1
19024         local file2=$DIR/$tdir/$tfile-2
19025         local file3=$DIR/$tdir/$tfile-3
19026         local lovea1
19027         local lovea2
19028
19029         mkdir -p $DIR/$tdir
19030         touch $file1 || error "create $file1 failed"
19031         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19032                 error "create $file2 failed"
19033         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19034                 error "create $file3 failed"
19035         lovea1=$(get_layout_param $file1)
19036
19037         $LFS swap_layouts $file2 $file3 ||
19038                 error "swap $file2 $file3 layouts failed"
19039         $LFS swap_layouts $file1 $file2 ||
19040                 error "swap $file1 $file2 layouts failed"
19041
19042         lovea2=$(get_layout_param $file2)
19043         echo "$lovea1"
19044         echo "$lovea2"
19045         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19046
19047         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19048         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19049 }
19050 run_test 184d "allow stripeless layouts swap"
19051
19052 test_184e() {
19053         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19054                 skip "Need MDS version at least 2.6.94"
19055         check_swap_layouts_support
19056         check_swap_layout_no_dom $DIR
19057         [ -z "$(which getfattr 2>/dev/null)" ] &&
19058                 skip_env "no getfattr command"
19059
19060         local file1=$DIR/$tdir/$tfile-1
19061         local file2=$DIR/$tdir/$tfile-2
19062         local file3=$DIR/$tdir/$tfile-3
19063         local lovea
19064
19065         mkdir -p $DIR/$tdir
19066         touch $file1 || error "create $file1 failed"
19067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19068                 error "create $file2 failed"
19069         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19070                 error "create $file3 failed"
19071
19072         $LFS swap_layouts $file1 $file2 ||
19073                 error "swap $file1 $file2 layouts failed"
19074
19075         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19076         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19077
19078         echo 123 > $file1 || error "Should be able to write into $file1"
19079
19080         $LFS swap_layouts $file1 $file3 ||
19081                 error "swap $file1 $file3 layouts failed"
19082
19083         echo 123 > $file1 || error "Should be able to write into $file1"
19084
19085         rm -rf $file1 $file2 $file3
19086 }
19087 run_test 184e "Recreate layout after stripeless layout swaps"
19088
19089 test_184f() {
19090         # Create a file with name longer than sizeof(struct stat) ==
19091         # 144 to see if we can get chars from the file name to appear
19092         # in the returned striping. Note that 'f' == 0x66.
19093         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19094
19095         mkdir -p $DIR/$tdir
19096         mcreate $DIR/$tdir/$file
19097         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19098                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19099         fi
19100 }
19101 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19102
19103 test_185() { # LU-2441
19104         # LU-3553 - no volatile file support in old servers
19105         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19106                 skip "Need MDS version at least 2.3.60"
19107
19108         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19109         touch $DIR/$tdir/spoo
19110         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19111         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19112                 error "cannot create/write a volatile file"
19113         [ "$FILESET" == "" ] &&
19114         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19115                 error "FID is still valid after close"
19116
19117         multiop_bg_pause $DIR/$tdir vVw4096_c
19118         local multi_pid=$!
19119
19120         local OLD_IFS=$IFS
19121         IFS=":"
19122         local fidv=($fid)
19123         IFS=$OLD_IFS
19124         # assume that the next FID for this client is sequential, since stdout
19125         # is unfortunately eaten by multiop_bg_pause
19126         local n=$((${fidv[1]} + 1))
19127         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19128         if [ "$FILESET" == "" ]; then
19129                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19130                         error "FID is missing before close"
19131         fi
19132         kill -USR1 $multi_pid
19133         # 1 second delay, so if mtime change we will see it
19134         sleep 1
19135         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19136         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19137 }
19138 run_test 185 "Volatile file support"
19139
19140 function create_check_volatile() {
19141         local idx=$1
19142         local tgt
19143
19144         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19145         local PID=$!
19146         sleep 1
19147         local FID=$(cat /tmp/${tfile}.fid)
19148         [ "$FID" == "" ] && error "can't get FID for volatile"
19149         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19150         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19151         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19152         kill -USR1 $PID
19153         wait
19154         sleep 1
19155         cancel_lru_locks mdc # flush opencache
19156         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19157         return 0
19158 }
19159
19160 test_185a(){
19161         # LU-12516 - volatile creation via .lustre
19162         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19163                 skip "Need MDS version at least 2.3.55"
19164
19165         create_check_volatile 0
19166         [ $MDSCOUNT -lt 2 ] && return 0
19167
19168         # DNE case
19169         create_check_volatile 1
19170
19171         return 0
19172 }
19173 run_test 185a "Volatile file creation in .lustre/fid/"
19174
19175 test_187a() {
19176         remote_mds_nodsh && skip "remote MDS with nodsh"
19177         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19178                 skip "Need MDS version at least 2.3.0"
19179
19180         local dir0=$DIR/$tdir/$testnum
19181         mkdir -p $dir0 || error "creating dir $dir0"
19182
19183         local file=$dir0/file1
19184         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19185         local dv1=$($LFS data_version $file)
19186         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19187         local dv2=$($LFS data_version $file)
19188         [[ $dv1 != $dv2 ]] ||
19189                 error "data version did not change on write $dv1 == $dv2"
19190
19191         # clean up
19192         rm -f $file1
19193 }
19194 run_test 187a "Test data version change"
19195
19196 test_187b() {
19197         remote_mds_nodsh && skip "remote MDS with nodsh"
19198         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19199                 skip "Need MDS version at least 2.3.0"
19200
19201         local dir0=$DIR/$tdir/$testnum
19202         mkdir -p $dir0 || error "creating dir $dir0"
19203
19204         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19205         [[ ${DV[0]} != ${DV[1]} ]] ||
19206                 error "data version did not change on write"\
19207                       " ${DV[0]} == ${DV[1]}"
19208
19209         # clean up
19210         rm -f $file1
19211 }
19212 run_test 187b "Test data version change on volatile file"
19213
19214 test_200() {
19215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19216         remote_mgs_nodsh && skip "remote MGS with nodsh"
19217         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19218
19219         local POOL=${POOL:-cea1}
19220         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19221         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19222         # Pool OST targets
19223         local first_ost=0
19224         local last_ost=$(($OSTCOUNT - 1))
19225         local ost_step=2
19226         local ost_list=$(seq $first_ost $ost_step $last_ost)
19227         local ost_range="$first_ost $last_ost $ost_step"
19228         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19229         local file_dir=$POOL_ROOT/file_tst
19230         local subdir=$test_path/subdir
19231         local rc=0
19232
19233         while : ; do
19234                 # former test_200a test_200b
19235                 pool_add $POOL                          || { rc=$? ; break; }
19236                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19237                 # former test_200c test_200d
19238                 mkdir -p $test_path
19239                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19240                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19241                 mkdir -p $subdir
19242                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19243                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19244                                                         || { rc=$? ; break; }
19245                 # former test_200e test_200f
19246                 local files=$((OSTCOUNT*3))
19247                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19248                                                         || { rc=$? ; break; }
19249                 pool_create_files $POOL $file_dir $files "$ost_list" \
19250                                                         || { rc=$? ; break; }
19251                 # former test_200g test_200h
19252                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19253                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19254
19255                 # former test_201a test_201b test_201c
19256                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19257
19258                 local f=$test_path/$tfile
19259                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19260                 pool_remove $POOL $f                    || { rc=$? ; break; }
19261                 break
19262         done
19263
19264         destroy_test_pools
19265
19266         return $rc
19267 }
19268 run_test 200 "OST pools"
19269
19270 # usage: default_attr <count | size | offset>
19271 default_attr() {
19272         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19273 }
19274
19275 # usage: check_default_stripe_attr
19276 check_default_stripe_attr() {
19277         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19278         case $1 in
19279         --stripe-count|-c)
19280                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19281         --stripe-size|-S)
19282                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19283         --stripe-index|-i)
19284                 EXPECTED=-1;;
19285         *)
19286                 error "unknown getstripe attr '$1'"
19287         esac
19288
19289         [ $ACTUAL == $EXPECTED ] ||
19290                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19291 }
19292
19293 test_204a() {
19294         test_mkdir $DIR/$tdir
19295         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19296
19297         check_default_stripe_attr --stripe-count
19298         check_default_stripe_attr --stripe-size
19299         check_default_stripe_attr --stripe-index
19300 }
19301 run_test 204a "Print default stripe attributes"
19302
19303 test_204b() {
19304         test_mkdir $DIR/$tdir
19305         $LFS setstripe --stripe-count 1 $DIR/$tdir
19306
19307         check_default_stripe_attr --stripe-size
19308         check_default_stripe_attr --stripe-index
19309 }
19310 run_test 204b "Print default stripe size and offset"
19311
19312 test_204c() {
19313         test_mkdir $DIR/$tdir
19314         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19315
19316         check_default_stripe_attr --stripe-count
19317         check_default_stripe_attr --stripe-index
19318 }
19319 run_test 204c "Print default stripe count and offset"
19320
19321 test_204d() {
19322         test_mkdir $DIR/$tdir
19323         $LFS setstripe --stripe-index 0 $DIR/$tdir
19324
19325         check_default_stripe_attr --stripe-count
19326         check_default_stripe_attr --stripe-size
19327 }
19328 run_test 204d "Print default stripe count and size"
19329
19330 test_204e() {
19331         test_mkdir $DIR/$tdir
19332         $LFS setstripe -d $DIR/$tdir
19333
19334         check_default_stripe_attr --stripe-count --raw
19335         check_default_stripe_attr --stripe-size --raw
19336         check_default_stripe_attr --stripe-index --raw
19337 }
19338 run_test 204e "Print raw stripe attributes"
19339
19340 test_204f() {
19341         test_mkdir $DIR/$tdir
19342         $LFS setstripe --stripe-count 1 $DIR/$tdir
19343
19344         check_default_stripe_attr --stripe-size --raw
19345         check_default_stripe_attr --stripe-index --raw
19346 }
19347 run_test 204f "Print raw stripe size and offset"
19348
19349 test_204g() {
19350         test_mkdir $DIR/$tdir
19351         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19352
19353         check_default_stripe_attr --stripe-count --raw
19354         check_default_stripe_attr --stripe-index --raw
19355 }
19356 run_test 204g "Print raw stripe count and offset"
19357
19358 test_204h() {
19359         test_mkdir $DIR/$tdir
19360         $LFS setstripe --stripe-index 0 $DIR/$tdir
19361
19362         check_default_stripe_attr --stripe-count --raw
19363         check_default_stripe_attr --stripe-size --raw
19364 }
19365 run_test 204h "Print raw stripe count and size"
19366
19367 # Figure out which job scheduler is being used, if any,
19368 # or use a fake one
19369 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19370         JOBENV=SLURM_JOB_ID
19371 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19372         JOBENV=LSB_JOBID
19373 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19374         JOBENV=PBS_JOBID
19375 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19376         JOBENV=LOADL_STEP_ID
19377 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19378         JOBENV=JOB_ID
19379 else
19380         $LCTL list_param jobid_name > /dev/null 2>&1
19381         if [ $? -eq 0 ]; then
19382                 JOBENV=nodelocal
19383         else
19384                 JOBENV=FAKE_JOBID
19385         fi
19386 fi
19387 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19388
19389 verify_jobstats() {
19390         local cmd=($1)
19391         shift
19392         local facets="$@"
19393
19394 # we don't really need to clear the stats for this test to work, since each
19395 # command has a unique jobid, but it makes debugging easier if needed.
19396 #       for facet in $facets; do
19397 #               local dev=$(convert_facet2label $facet)
19398 #               # clear old jobstats
19399 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19400 #       done
19401
19402         # use a new JobID for each test, or we might see an old one
19403         [ "$JOBENV" = "FAKE_JOBID" ] &&
19404                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19405
19406         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19407
19408         [ "$JOBENV" = "nodelocal" ] && {
19409                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19410                 $LCTL set_param jobid_name=$FAKE_JOBID
19411                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19412         }
19413
19414         log "Test: ${cmd[*]}"
19415         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19416
19417         if [ $JOBENV = "FAKE_JOBID" ]; then
19418                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19419         else
19420                 ${cmd[*]}
19421         fi
19422
19423         # all files are created on OST0000
19424         for facet in $facets; do
19425                 local stats="*.$(convert_facet2label $facet).job_stats"
19426
19427                 # strip out libtool wrappers for in-tree executables
19428                 if (( $(do_facet $facet lctl get_param $stats |
19429                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19430                         do_facet $facet lctl get_param $stats
19431                         error "No jobstats for $JOBVAL found on $facet::$stats"
19432                 fi
19433         done
19434 }
19435
19436 jobstats_set() {
19437         local new_jobenv=$1
19438
19439         set_persistent_param_and_check client "jobid_var" \
19440                 "$FSNAME.sys.jobid_var" $new_jobenv
19441 }
19442
19443 test_205a() { # Job stats
19444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19445         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19446                 skip "Need MDS version with at least 2.7.1"
19447         remote_mgs_nodsh && skip "remote MGS with nodsh"
19448         remote_mds_nodsh && skip "remote MDS with nodsh"
19449         remote_ost_nodsh && skip "remote OST with nodsh"
19450         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19451                 skip "Server doesn't support jobstats"
19452         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19453
19454         local old_jobenv=$($LCTL get_param -n jobid_var)
19455         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19456         stack_trap "jobstats_set $old_jobenv" EXIT
19457
19458         changelog_register
19459
19460         local old_jobid_name=$($LCTL get_param jobid_name)
19461         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19462
19463         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19464                                 mdt.*.job_cleanup_interval | head -n 1)
19465         local new_interval=5
19466         do_facet $SINGLEMDS \
19467                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19468         stack_trap "do_facet $SINGLEMDS \
19469                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19470         local start=$SECONDS
19471
19472         local cmd
19473         # mkdir
19474         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19475         verify_jobstats "$cmd" "$SINGLEMDS"
19476         # rmdir
19477         cmd="rmdir $DIR/$tdir"
19478         verify_jobstats "$cmd" "$SINGLEMDS"
19479         # mkdir on secondary MDT
19480         if [ $MDSCOUNT -gt 1 ]; then
19481                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19482                 verify_jobstats "$cmd" "mds2"
19483         fi
19484         # mknod
19485         cmd="mknod $DIR/$tfile c 1 3"
19486         verify_jobstats "$cmd" "$SINGLEMDS"
19487         # unlink
19488         cmd="rm -f $DIR/$tfile"
19489         verify_jobstats "$cmd" "$SINGLEMDS"
19490         # create all files on OST0000 so verify_jobstats can find OST stats
19491         # open & close
19492         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19493         verify_jobstats "$cmd" "$SINGLEMDS"
19494         # setattr
19495         cmd="touch $DIR/$tfile"
19496         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19497         # write
19498         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19499         verify_jobstats "$cmd" "ost1"
19500         # read
19501         cancel_lru_locks osc
19502         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19503         verify_jobstats "$cmd" "ost1"
19504         # truncate
19505         cmd="$TRUNCATE $DIR/$tfile 0"
19506         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19507         # rename
19508         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19509         verify_jobstats "$cmd" "$SINGLEMDS"
19510         # jobstats expiry - sleep until old stats should be expired
19511         local left=$((new_interval + 5 - (SECONDS - start)))
19512         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19513                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19514                         "0" $left
19515         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19516         verify_jobstats "$cmd" "$SINGLEMDS"
19517         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19518             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19519
19520         # Ensure that jobid are present in changelog (if supported by MDS)
19521         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19522                 changelog_dump | tail -10
19523                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19524                 [ $jobids -eq 9 ] ||
19525                         error "Wrong changelog jobid count $jobids != 9"
19526
19527                 # LU-5862
19528                 JOBENV="disable"
19529                 jobstats_set $JOBENV
19530                 touch $DIR/$tfile
19531                 changelog_dump | grep $tfile
19532                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19533                 [ $jobids -eq 0 ] ||
19534                         error "Unexpected jobids when jobid_var=$JOBENV"
19535         fi
19536
19537         # test '%j' access to environment variable - if supported
19538         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19539                 JOBENV="JOBCOMPLEX"
19540                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19541
19542                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19543         fi
19544
19545         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19546                 JOBENV="JOBCOMPLEX"
19547                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19548
19549                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19550         fi
19551
19552         # test '%j' access to per-session jobid - if supported
19553         if lctl list_param jobid_this_session > /dev/null 2>&1
19554         then
19555                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19556                 lctl set_param jobid_this_session=$USER
19557
19558                 JOBENV="JOBCOMPLEX"
19559                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19560
19561                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19562         fi
19563 }
19564 run_test 205a "Verify job stats"
19565
19566 # LU-13117, LU-13597, LU-16599
19567 test_205b() {
19568         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19569                 skip "Need MDS version at least 2.13.54.91"
19570
19571         local job_stats="mdt.*.job_stats"
19572         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19573
19574         do_facet mds1 $LCTL set_param $job_stats=clear
19575
19576         # Setting jobid_var to USER might not be supported
19577         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19578         $LCTL set_param jobid_var=USER || true
19579         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19580         $LCTL set_param jobid_name="%j.%e.%u"
19581
19582         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19583         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19584                 { do_facet mds1 $LCTL get_param $job_stats;
19585                   error "Unexpected jobid found"; }
19586         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19587                 { do_facet mds1 $LCTL get_param $job_stats;
19588                   error "wrong job_stats format found"; }
19589
19590         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19591                 echo "MDS does not yet escape jobid" && return 0
19592
19593         mkdir_on_mdt0 $DIR/$tdir
19594         $LCTL set_param jobid_var=TEST205b
19595         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19596         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19597                       awk '/has\\x20sp/ {print $3}')
19598         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19599                   error "jobid not escaped"; }
19600
19601         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19602                 # need to run such a command on mds1:
19603                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19604                 #
19605                 # there might be multiple MDTs on single mds server, so need to
19606                 # specifiy MDT0000. Or the command will fail due to other MDTs
19607                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19608                         error "cannot clear escaped jobid in job_stats";
19609         else
19610                 echo "MDS does not support clearing escaped jobid"
19611         fi
19612 }
19613 run_test 205b "Verify job stats jobid and output format"
19614
19615 # LU-13733
19616 test_205c() {
19617         $LCTL set_param llite.*.stats=0
19618         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19619         $LCTL get_param llite.*.stats
19620         $LCTL get_param llite.*.stats | grep \
19621                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19622                         error "wrong client stats format found"
19623 }
19624 run_test 205c "Verify client stats format"
19625
19626 test_205d() {
19627         local file=$DIR/$tdir/$tfile
19628
19629         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19630                 skip "need lustre >= 2.15.53 for lljobstat"
19631         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19632                 skip "need lustre >= 2.15.53 for lljobstat"
19633         verify_yaml_available || skip_env "YAML verification not installed"
19634
19635         test_mkdir -i 0 $DIR/$tdir
19636         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19637
19638         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19639                 error "failed to write data to $file"
19640         mv $file $file.2
19641
19642         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19643         echo -n 'verify rename_stats...'
19644         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19645                 verify_yaml || error "rename_stats is not valid YAML"
19646         echo " OK"
19647
19648         echo -n 'verify mdt job_stats...'
19649         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19650                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19651         echo " OK"
19652
19653         echo -n 'verify ost job_stats...'
19654         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19655                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19656         echo " OK"
19657 }
19658 run_test 205d "verify the format of some stats files"
19659
19660 test_205e() {
19661         local ops_comma
19662         local file=$DIR/$tdir/$tfile
19663         local -a cli_params
19664
19665         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19666                 skip "need lustre >= 2.15.53 for lljobstat"
19667         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19668                 skip "need lustre >= 2.15.53 for lljobstat"
19669         verify_yaml_available || skip_env "YAML verification not installed"
19670
19671         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19672         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19673         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19674
19675         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19676
19677         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19678                 error "failed to create $file on ost1"
19679         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19680                 error "failed to write data to $file"
19681
19682         do_facet mds1 "$LCTL get_param *.*.job_stats"
19683         do_facet ost1 "$LCTL get_param *.*.job_stats"
19684
19685         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19686         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19687                 error "The output of lljobstat is not an valid YAML"
19688
19689         # verify that job dd.0 does exist and has some ops on ost1
19690         # typically this line is like:
19691         # - 205e.dd.0:            {ops: 20, ...}
19692         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19693                     awk '$2=="205e.dd.0:" {print $4}')
19694
19695         (( ${ops_comma%,} >= 10 )) ||
19696                 error "cannot find job 205e.dd.0 with ops >= 10"
19697 }
19698 run_test 205e "verify the output of lljobstat"
19699
19700 test_205f() {
19701         verify_yaml_available || skip_env "YAML verification not installed"
19702
19703         # check both qos_ost_weights and qos_mdt_weights
19704         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19705         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19706                 error "qos_ost_weights is not valid YAML"
19707 }
19708 run_test 205f "verify qos_ost_weights YAML format "
19709
19710 __test_205_jobstats_dump() {
19711         local -a pids
19712         local nbr_instance=$1
19713
19714         while true; do
19715                 if (( ${#pids[@]} >= nbr_instance )); then
19716                         wait ${pids[@]}
19717                         pids=()
19718                 fi
19719
19720                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19721                 pids+=( $! )
19722         done
19723 }
19724
19725 __test_205_cleanup() {
19726         kill $@
19727         # Clear all job entries
19728         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19729 }
19730
19731 test_205g() {
19732         local -a mds1_params
19733         local -a cli_params
19734         local pids
19735         local interval=5
19736
19737         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19738         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19739         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19740
19741         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19742         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19743         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19744
19745         # start jobs loop
19746         export TEST205G_ID=205g
19747         stack_trap "unset TEST205G_ID" EXIT
19748         while true; do
19749                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19750         done & pids="$! "
19751
19752         __test_205_jobstats_dump 4 & pids+="$! "
19753         stack_trap "__test_205_cleanup $pids" EXIT INT
19754
19755         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19756 }
19757 run_test 205g "stress test for job_stats procfile"
19758
19759 # LU-1480, LU-1773 and LU-1657
19760 test_206() {
19761         mkdir -p $DIR/$tdir
19762         $LFS setstripe -c -1 $DIR/$tdir
19763 #define OBD_FAIL_LOV_INIT 0x1403
19764         $LCTL set_param fail_loc=0xa0001403
19765         $LCTL set_param fail_val=1
19766         touch $DIR/$tdir/$tfile || true
19767 }
19768 run_test 206 "fail lov_init_raid0() doesn't lbug"
19769
19770 test_207a() {
19771         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19772         local fsz=`stat -c %s $DIR/$tfile`
19773         cancel_lru_locks mdc
19774
19775         # do not return layout in getattr intent
19776 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19777         $LCTL set_param fail_loc=0x170
19778         local sz=`stat -c %s $DIR/$tfile`
19779
19780         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19781
19782         rm -rf $DIR/$tfile
19783 }
19784 run_test 207a "can refresh layout at glimpse"
19785
19786 test_207b() {
19787         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19788         local cksum=`md5sum $DIR/$tfile`
19789         local fsz=`stat -c %s $DIR/$tfile`
19790         cancel_lru_locks mdc
19791         cancel_lru_locks osc
19792
19793         # do not return layout in getattr intent
19794 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19795         $LCTL set_param fail_loc=0x171
19796
19797         # it will refresh layout after the file is opened but before read issues
19798         echo checksum is "$cksum"
19799         echo "$cksum" |md5sum -c --quiet || error "file differs"
19800
19801         rm -rf $DIR/$tfile
19802 }
19803 run_test 207b "can refresh layout at open"
19804
19805 test_208() {
19806         # FIXME: in this test suite, only RD lease is used. This is okay
19807         # for now as only exclusive open is supported. After generic lease
19808         # is done, this test suite should be revised. - Jinshan
19809
19810         remote_mds_nodsh && skip "remote MDS with nodsh"
19811         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19812                 skip "Need MDS version at least 2.4.52"
19813
19814         echo "==== test 1: verify get lease work"
19815         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19816
19817         echo "==== test 2: verify lease can be broken by upcoming open"
19818         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19819         local PID=$!
19820         sleep 2
19821
19822         $MULTIOP $DIR/$tfile oO_RDWR:c
19823         kill -USR1 $PID && wait $PID || error "break lease error"
19824
19825         echo "==== test 3: verify lease can't be granted if an open already exists"
19826         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19827         local PID=$!
19828         sleep 2
19829
19830         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19831         kill -USR1 $PID && wait $PID || error "open file error"
19832
19833         echo "==== test 4: lease can sustain over recovery"
19834         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19835         PID=$!
19836         sleep 2
19837
19838         fail mds1
19839
19840         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19841
19842         echo "==== test 5: lease broken can't be regained by replay"
19843         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19844         PID=$!
19845         sleep 2
19846
19847         # open file to break lease and then recovery
19848         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19849         fail mds1
19850
19851         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19852
19853         rm -f $DIR/$tfile
19854 }
19855 run_test 208 "Exclusive open"
19856
19857 test_209() {
19858         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19859                 skip_env "must have disp_stripe"
19860
19861         touch $DIR/$tfile
19862         sync; sleep 5; sync;
19863
19864         echo 3 > /proc/sys/vm/drop_caches
19865         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19866                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19867         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19868
19869         # open/close 500 times
19870         for i in $(seq 500); do
19871                 cat $DIR/$tfile
19872         done
19873
19874         echo 3 > /proc/sys/vm/drop_caches
19875         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19876                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19877         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19878
19879         echo "before: $req_before, after: $req_after"
19880         [ $((req_after - req_before)) -ge 300 ] &&
19881                 error "open/close requests are not freed"
19882         return 0
19883 }
19884 run_test 209 "read-only open/close requests should be freed promptly"
19885
19886 test_210() {
19887         local pid
19888
19889         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19890         pid=$!
19891         sleep 1
19892
19893         $LFS getstripe $DIR/$tfile
19894         kill -USR1 $pid
19895         wait $pid || error "multiop failed"
19896
19897         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19898         pid=$!
19899         sleep 1
19900
19901         $LFS getstripe $DIR/$tfile
19902         kill -USR1 $pid
19903         wait $pid || error "multiop failed"
19904 }
19905 run_test 210 "lfs getstripe does not break leases"
19906
19907 test_212() {
19908         size=`date +%s`
19909         size=$((size % 8192 + 1))
19910         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19911         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19912         rm -f $DIR/f212 $DIR/f212.xyz
19913 }
19914 run_test 212 "Sendfile test ============================================"
19915
19916 test_213() {
19917         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19918         cancel_lru_locks osc
19919         lctl set_param fail_loc=0x8000040f
19920         # generate a read lock
19921         cat $DIR/$tfile > /dev/null
19922         # write to the file, it will try to cancel the above read lock.
19923         cat /etc/hosts >> $DIR/$tfile
19924 }
19925 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19926
19927 test_214() { # for bug 20133
19928         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19929         for (( i=0; i < 340; i++ )) ; do
19930                 touch $DIR/$tdir/d214c/a$i
19931         done
19932
19933         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19934         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19935         ls $DIR/d214c || error "ls $DIR/d214c failed"
19936         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19937         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19938 }
19939 run_test 214 "hash-indexed directory test - bug 20133"
19940
19941 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19942 create_lnet_proc_files() {
19943         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19944 }
19945
19946 # counterpart of create_lnet_proc_files
19947 remove_lnet_proc_files() {
19948         rm -f $TMP/lnet_$1.sys
19949 }
19950
19951 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19952 # 3rd arg as regexp for body
19953 check_lnet_proc_stats() {
19954         local l=$(cat "$TMP/lnet_$1" |wc -l)
19955         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19956
19957         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19958 }
19959
19960 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19961 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19962 # optional and can be regexp for 2nd line (lnet.routes case)
19963 check_lnet_proc_entry() {
19964         local blp=2          # blp stands for 'position of 1st line of body'
19965         [ -z "$5" ] || blp=3 # lnet.routes case
19966
19967         local l=$(cat "$TMP/lnet_$1" |wc -l)
19968         # subtracting one from $blp because the body can be empty
19969         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19970
19971         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19972                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19973
19974         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19975                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19976
19977         # bail out if any unexpected line happened
19978         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19979         [ "$?" != 0 ] || error "$2 misformatted"
19980 }
19981
19982 test_215() { # for bugs 18102, 21079, 21517
19983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19984
19985         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19986         local P='[1-9][0-9]*'           # positive numeric
19987         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19988         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19989         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19990         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19991
19992         local L1 # regexp for 1st line
19993         local L2 # regexp for 2nd line (optional)
19994         local BR # regexp for the rest (body)
19995
19996         # lnet.stats should look as 11 space-separated non-negative numerics
19997         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19998         create_lnet_proc_files "stats"
19999         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20000         remove_lnet_proc_files "stats"
20001
20002         # lnet.routes should look like this:
20003         # Routing disabled/enabled
20004         # net hops priority state router
20005         # where net is a string like tcp0, hops > 0, priority >= 0,
20006         # state is up/down,
20007         # router is a string like 192.168.1.1@tcp2
20008         L1="^Routing (disabled|enabled)$"
20009         L2="^net +hops +priority +state +router$"
20010         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20011         create_lnet_proc_files "routes"
20012         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20013         remove_lnet_proc_files "routes"
20014
20015         # lnet.routers should look like this:
20016         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20017         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20018         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20019         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20020         L1="^ref +rtr_ref +alive +router$"
20021         BR="^$P +$P +(up|down) +$NID$"
20022         create_lnet_proc_files "routers"
20023         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20024         remove_lnet_proc_files "routers"
20025
20026         # lnet.peers should look like this:
20027         # nid refs state last max rtr min tx min queue
20028         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20029         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20030         # numeric (0 or >0 or <0), queue >= 0.
20031         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20032         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20033         create_lnet_proc_files "peers"
20034         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20035         remove_lnet_proc_files "peers"
20036
20037         # lnet.buffers  should look like this:
20038         # pages count credits min
20039         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20040         L1="^pages +count +credits +min$"
20041         BR="^ +$N +$N +$I +$I$"
20042         create_lnet_proc_files "buffers"
20043         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20044         remove_lnet_proc_files "buffers"
20045
20046         # lnet.nis should look like this:
20047         # nid status alive refs peer rtr max tx min
20048         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20049         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20050         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20051         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20052         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20053         create_lnet_proc_files "nis"
20054         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20055         remove_lnet_proc_files "nis"
20056
20057         # can we successfully write to lnet.stats?
20058         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20059 }
20060 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20061
20062 test_216() { # bug 20317
20063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20064         remote_ost_nodsh && skip "remote OST with nodsh"
20065
20066         local node
20067         local facets=$(get_facets OST)
20068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20069
20070         save_lustre_params client "osc.*.contention_seconds" > $p
20071         save_lustre_params $facets \
20072                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20073         save_lustre_params $facets \
20074                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20075         save_lustre_params $facets \
20076                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20077         clear_stats osc.*.osc_stats
20078
20079         # agressive lockless i/o settings
20080         do_nodes $(comma_list $(osts_nodes)) \
20081                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20082                         ldlm.namespaces.filter-*.contended_locks=0 \
20083                         ldlm.namespaces.filter-*.contention_seconds=60"
20084         lctl set_param -n osc.*.contention_seconds=60
20085
20086         $DIRECTIO write $DIR/$tfile 0 10 4096
20087         $CHECKSTAT -s 40960 $DIR/$tfile
20088
20089         # disable lockless i/o
20090         do_nodes $(comma_list $(osts_nodes)) \
20091                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20092                         ldlm.namespaces.filter-*.contended_locks=32 \
20093                         ldlm.namespaces.filter-*.contention_seconds=0"
20094         lctl set_param -n osc.*.contention_seconds=0
20095         clear_stats osc.*.osc_stats
20096
20097         dd if=/dev/zero of=$DIR/$tfile count=0
20098         $CHECKSTAT -s 0 $DIR/$tfile
20099
20100         restore_lustre_params <$p
20101         rm -f $p
20102         rm $DIR/$tfile
20103 }
20104 run_test 216 "check lockless direct write updates file size and kms correctly"
20105
20106 test_217() { # bug 22430
20107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20108
20109         local node
20110         local nid
20111
20112         for node in $(nodes_list); do
20113                 nid=$(host_nids_address $node $NETTYPE)
20114                 if [[ $nid = *-* ]] ; then
20115                         echo "lctl ping $(h2nettype $nid)"
20116                         lctl ping $(h2nettype $nid)
20117                 else
20118                         echo "skipping $node (no hyphen detected)"
20119                 fi
20120         done
20121 }
20122 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
20123
20124 test_218() {
20125        # do directio so as not to populate the page cache
20126        log "creating a 10 Mb file"
20127        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
20128        log "starting reads"
20129        dd if=$DIR/$tfile of=/dev/null bs=4096 &
20130        log "truncating the file"
20131        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
20132        log "killing dd"
20133        kill %+ || true # reads might have finished
20134        echo "wait until dd is finished"
20135        wait
20136        log "removing the temporary file"
20137        rm -rf $DIR/$tfile || error "tmp file removal failed"
20138 }
20139 run_test 218 "parallel read and truncate should not deadlock"
20140
20141 test_219() {
20142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20143
20144         # write one partial page
20145         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20146         # set no grant so vvp_io_commit_write will do sync write
20147         $LCTL set_param fail_loc=0x411
20148         # write a full page at the end of file
20149         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20150
20151         $LCTL set_param fail_loc=0
20152         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20153         $LCTL set_param fail_loc=0x411
20154         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20155
20156         # LU-4201
20157         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20158         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20159 }
20160 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20161
20162 test_220() { #LU-325
20163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20164         remote_ost_nodsh && skip "remote OST with nodsh"
20165         remote_mds_nodsh && skip "remote MDS with nodsh"
20166         remote_mgs_nodsh && skip "remote MGS with nodsh"
20167
20168         local OSTIDX=0
20169
20170         # create on MDT0000 so the last_id and next_id are correct
20171         mkdir_on_mdt0 $DIR/$tdir
20172         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20173         OST=${OST%_UUID}
20174
20175         # on the mdt's osc
20176         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20177         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20178                         osp.$mdtosc_proc1.prealloc_last_id)
20179         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20180                         osp.$mdtosc_proc1.prealloc_next_id)
20181
20182         $LFS df -i
20183
20184         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20185         #define OBD_FAIL_OST_ENOINO              0x229
20186         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20187         create_pool $FSNAME.$TESTNAME || return 1
20188         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20189
20190         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20191
20192         MDSOBJS=$((last_id - next_id))
20193         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20194
20195         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20196         echo "OST still has $count kbytes free"
20197
20198         echo "create $MDSOBJS files @next_id..."
20199         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20200
20201         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20202                         osp.$mdtosc_proc1.prealloc_last_id)
20203         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20204                         osp.$mdtosc_proc1.prealloc_next_id)
20205
20206         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20207         $LFS df -i
20208
20209         echo "cleanup..."
20210
20211         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20212         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20213
20214         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20215                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20216         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20217                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20218         echo "unlink $MDSOBJS files @$next_id..."
20219         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20220 }
20221 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20222
20223 test_221() {
20224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20225
20226         dd if=`which date` of=$MOUNT/date oflag=sync
20227         chmod +x $MOUNT/date
20228
20229         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20230         $LCTL set_param fail_loc=0x80001401
20231
20232         $MOUNT/date > /dev/null
20233         rm -f $MOUNT/date
20234 }
20235 run_test 221 "make sure fault and truncate race to not cause OOM"
20236
20237 test_222a () {
20238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20239
20240         rm -rf $DIR/$tdir
20241         test_mkdir $DIR/$tdir
20242         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20243         createmany -o $DIR/$tdir/$tfile 10
20244         cancel_lru_locks mdc
20245         cancel_lru_locks osc
20246         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20247         $LCTL set_param fail_loc=0x31a
20248         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20249         $LCTL set_param fail_loc=0
20250         rm -r $DIR/$tdir
20251 }
20252 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20253
20254 test_222b () {
20255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20256
20257         rm -rf $DIR/$tdir
20258         test_mkdir $DIR/$tdir
20259         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20260         createmany -o $DIR/$tdir/$tfile 10
20261         cancel_lru_locks mdc
20262         cancel_lru_locks osc
20263         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20264         $LCTL set_param fail_loc=0x31a
20265         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20266         $LCTL set_param fail_loc=0
20267 }
20268 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20269
20270 test_223 () {
20271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20272
20273         rm -rf $DIR/$tdir
20274         test_mkdir $DIR/$tdir
20275         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20276         createmany -o $DIR/$tdir/$tfile 10
20277         cancel_lru_locks mdc
20278         cancel_lru_locks osc
20279         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20280         $LCTL set_param fail_loc=0x31b
20281         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20282         $LCTL set_param fail_loc=0
20283         rm -r $DIR/$tdir
20284 }
20285 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20286
20287 test_224a() { # LU-1039, MRP-303
20288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20289         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20290         $LCTL set_param fail_loc=0x508
20291         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20292         $LCTL set_param fail_loc=0
20293         df $DIR
20294 }
20295 run_test 224a "Don't panic on bulk IO failure"
20296
20297 test_224bd_sub() { # LU-1039, MRP-303
20298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20299         local timeout=$1
20300
20301         shift
20302         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20303
20304         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20305
20306         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20307         cancel_lru_locks osc
20308         set_checksums 0
20309         stack_trap "set_checksums $ORIG_CSUM" EXIT
20310         local at_max_saved=0
20311
20312         # adaptive timeouts may prevent seeing the issue
20313         if at_is_enabled; then
20314                 at_max_saved=$(at_max_get mds)
20315                 at_max_set 0 mds client
20316                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20317         fi
20318
20319         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20320         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20321         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20322
20323         do_facet ost1 $LCTL set_param fail_loc=0
20324         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20325         df $DIR
20326 }
20327
20328 test_224b() {
20329         test_224bd_sub 3 error "dd failed"
20330 }
20331 run_test 224b "Don't panic on bulk IO failure"
20332
20333 test_224c() { # LU-6441
20334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20335         remote_mds_nodsh && skip "remote MDS with nodsh"
20336
20337         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20338         save_writethrough $p
20339         set_cache writethrough on
20340
20341         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20342         local at_max=$($LCTL get_param -n at_max)
20343         local timeout=$($LCTL get_param -n timeout)
20344         local test_at="at_max"
20345         local param_at="$FSNAME.sys.at_max"
20346         local test_timeout="timeout"
20347         local param_timeout="$FSNAME.sys.timeout"
20348
20349         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20350
20351         set_persistent_param_and_check client "$test_at" "$param_at" 0
20352         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20353
20354         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20355         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20356         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20357         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20358         sync
20359         do_facet ost1 "$LCTL set_param fail_loc=0"
20360
20361         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20362         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20363                 $timeout
20364
20365         $LCTL set_param -n $pages_per_rpc
20366         restore_lustre_params < $p
20367         rm -f $p
20368 }
20369 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20370
20371 test_224d() { # LU-11169
20372         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20373 }
20374 run_test 224d "Don't corrupt data on bulk IO timeout"
20375
20376 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20377 test_225a () {
20378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20379         if [ -z ${MDSSURVEY} ]; then
20380                 skip_env "mds-survey not found"
20381         fi
20382         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20383                 skip "Need MDS version at least 2.2.51"
20384
20385         local mds=$(facet_host $SINGLEMDS)
20386         local target=$(do_nodes $mds 'lctl dl' |
20387                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20388
20389         local cmd1="file_count=1000 thrhi=4"
20390         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20391         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20392         local cmd="$cmd1 $cmd2 $cmd3"
20393
20394         rm -f ${TMP}/mds_survey*
20395         echo + $cmd
20396         eval $cmd || error "mds-survey with zero-stripe failed"
20397         cat ${TMP}/mds_survey*
20398         rm -f ${TMP}/mds_survey*
20399 }
20400 run_test 225a "Metadata survey sanity with zero-stripe"
20401
20402 test_225b () {
20403         if [ -z ${MDSSURVEY} ]; then
20404                 skip_env "mds-survey not found"
20405         fi
20406         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20407                 skip "Need MDS version at least 2.2.51"
20408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20409         remote_mds_nodsh && skip "remote MDS with nodsh"
20410         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20411                 skip_env "Need to mount OST to test"
20412         fi
20413
20414         local mds=$(facet_host $SINGLEMDS)
20415         local target=$(do_nodes $mds 'lctl dl' |
20416                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20417
20418         local cmd1="file_count=1000 thrhi=4"
20419         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20420         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20421         local cmd="$cmd1 $cmd2 $cmd3"
20422
20423         rm -f ${TMP}/mds_survey*
20424         echo + $cmd
20425         eval $cmd || error "mds-survey with stripe_count failed"
20426         cat ${TMP}/mds_survey*
20427         rm -f ${TMP}/mds_survey*
20428 }
20429 run_test 225b "Metadata survey sanity with stripe_count = 1"
20430
20431 mcreate_path2fid () {
20432         local mode=$1
20433         local major=$2
20434         local minor=$3
20435         local name=$4
20436         local desc=$5
20437         local path=$DIR/$tdir/$name
20438         local fid
20439         local rc
20440         local fid_path
20441
20442         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20443                 error "cannot create $desc"
20444
20445         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20446         rc=$?
20447         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20448
20449         fid_path=$($LFS fid2path $MOUNT $fid)
20450         rc=$?
20451         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20452
20453         [ "$path" == "$fid_path" ] ||
20454                 error "fid2path returned $fid_path, expected $path"
20455
20456         echo "pass with $path and $fid"
20457 }
20458
20459 test_226a () {
20460         rm -rf $DIR/$tdir
20461         mkdir -p $DIR/$tdir
20462
20463         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20464         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20465         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20466         mcreate_path2fid 0040666 0 0 dir "directory"
20467         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20468         mcreate_path2fid 0100666 0 0 file "regular file"
20469         mcreate_path2fid 0120666 0 0 link "symbolic link"
20470         mcreate_path2fid 0140666 0 0 sock "socket"
20471 }
20472 run_test 226a "call path2fid and fid2path on files of all type"
20473
20474 test_226b () {
20475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20476
20477         local MDTIDX=1
20478
20479         rm -rf $DIR/$tdir
20480         mkdir -p $DIR/$tdir
20481         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20482                 error "create remote directory failed"
20483         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20484         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20485                                 "character special file (null)"
20486         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20487                                 "character special file (no device)"
20488         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20489         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20490                                 "block special file (loop)"
20491         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20492         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20493         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20494 }
20495 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20496
20497 test_226c () {
20498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20499         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20500                 skip "Need MDS version at least 2.13.55"
20501
20502         local submnt=/mnt/submnt
20503         local srcfile=/etc/passwd
20504         local dstfile=$submnt/passwd
20505         local path
20506         local fid
20507
20508         rm -rf $DIR/$tdir
20509         rm -rf $submnt
20510         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20511                 error "create remote directory failed"
20512         mkdir -p $submnt || error "create $submnt failed"
20513         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20514                 error "mount $submnt failed"
20515         stack_trap "umount $submnt" EXIT
20516
20517         cp $srcfile $dstfile
20518         fid=$($LFS path2fid $dstfile)
20519         path=$($LFS fid2path $submnt "$fid")
20520         [ "$path" = "$dstfile" ] ||
20521                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20522 }
20523 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20524
20525 # LU-1299 Executing or running ldd on a truncated executable does not
20526 # cause an out-of-memory condition.
20527 test_227() {
20528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20529         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20530
20531         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20532         chmod +x $MOUNT/date
20533
20534         $MOUNT/date > /dev/null
20535         ldd $MOUNT/date > /dev/null
20536         rm -f $MOUNT/date
20537 }
20538 run_test 227 "running truncated executable does not cause OOM"
20539
20540 # LU-1512 try to reuse idle OI blocks
20541 test_228a() {
20542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20543         remote_mds_nodsh && skip "remote MDS with nodsh"
20544         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20545
20546         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20547         local myDIR=$DIR/$tdir
20548
20549         mkdir -p $myDIR
20550         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20551         $LCTL set_param fail_loc=0x80001002
20552         createmany -o $myDIR/t- 10000
20553         $LCTL set_param fail_loc=0
20554         # The guard is current the largest FID holder
20555         touch $myDIR/guard
20556         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20557                     tr -d '[')
20558         local IDX=$(($SEQ % 64))
20559
20560         do_facet $SINGLEMDS sync
20561         # Make sure journal flushed.
20562         sleep 6
20563         local blk1=$(do_facet $SINGLEMDS \
20564                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20565                      grep Blockcount | awk '{print $4}')
20566
20567         # Remove old files, some OI blocks will become idle.
20568         unlinkmany $myDIR/t- 10000
20569         # Create new files, idle OI blocks should be reused.
20570         createmany -o $myDIR/t- 2000
20571         do_facet $SINGLEMDS sync
20572         # Make sure journal flushed.
20573         sleep 6
20574         local blk2=$(do_facet $SINGLEMDS \
20575                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20576                      grep Blockcount | awk '{print $4}')
20577
20578         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20579 }
20580 run_test 228a "try to reuse idle OI blocks"
20581
20582 test_228b() {
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         createmany -o $myDIR/t- 10000
20594         $LCTL set_param fail_loc=0
20595         # The guard is current the largest FID holder
20596         touch $myDIR/guard
20597         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20598                     tr -d '[')
20599         local IDX=$(($SEQ % 64))
20600
20601         do_facet $SINGLEMDS sync
20602         # Make sure journal flushed.
20603         sleep 6
20604         local blk1=$(do_facet $SINGLEMDS \
20605                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20606                      grep Blockcount | awk '{print $4}')
20607
20608         # Remove old files, some OI blocks will become idle.
20609         unlinkmany $myDIR/t- 10000
20610
20611         # stop the MDT
20612         stop $SINGLEMDS || error "Fail to stop MDT."
20613         # remount the MDT
20614         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20615                 error "Fail to start MDT."
20616
20617         client_up || error "Fail to df."
20618         # Create new files, idle OI blocks should be reused.
20619         createmany -o $myDIR/t- 2000
20620         do_facet $SINGLEMDS sync
20621         # Make sure journal flushed.
20622         sleep 6
20623         local blk2=$(do_facet $SINGLEMDS \
20624                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20625                      grep Blockcount | awk '{print $4}')
20626
20627         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20628 }
20629 run_test 228b "idle OI blocks can be reused after MDT restart"
20630
20631 #LU-1881
20632 test_228c() {
20633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20634         remote_mds_nodsh && skip "remote MDS with nodsh"
20635         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20636
20637         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20638         local myDIR=$DIR/$tdir
20639
20640         mkdir -p $myDIR
20641         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20642         $LCTL set_param fail_loc=0x80001002
20643         # 20000 files can guarantee there are index nodes in the OI file
20644         createmany -o $myDIR/t- 20000
20645         $LCTL set_param fail_loc=0
20646         # The guard is current the largest FID holder
20647         touch $myDIR/guard
20648         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20649                     tr -d '[')
20650         local IDX=$(($SEQ % 64))
20651
20652         do_facet $SINGLEMDS sync
20653         # Make sure journal flushed.
20654         sleep 6
20655         local blk1=$(do_facet $SINGLEMDS \
20656                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20657                      grep Blockcount | awk '{print $4}')
20658
20659         # Remove old files, some OI blocks will become idle.
20660         unlinkmany $myDIR/t- 20000
20661         rm -f $myDIR/guard
20662         # The OI file should become empty now
20663
20664         # Create new files, idle OI blocks should be reused.
20665         createmany -o $myDIR/t- 2000
20666         do_facet $SINGLEMDS sync
20667         # Make sure journal flushed.
20668         sleep 6
20669         local blk2=$(do_facet $SINGLEMDS \
20670                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20671                      grep Blockcount | awk '{print $4}')
20672
20673         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20674 }
20675 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20676
20677 test_229() { # LU-2482, LU-3448
20678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20679         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20680         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20681                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20682
20683         rm -f $DIR/$tfile
20684
20685         # Create a file with a released layout and stripe count 2.
20686         $MULTIOP $DIR/$tfile H2c ||
20687                 error "failed to create file with released layout"
20688
20689         $LFS getstripe -v $DIR/$tfile
20690
20691         local pattern=$($LFS getstripe -L $DIR/$tfile)
20692         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20693
20694         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20695                 error "getstripe"
20696         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20697         stat $DIR/$tfile || error "failed to stat released file"
20698
20699         chown $RUNAS_ID $DIR/$tfile ||
20700                 error "chown $RUNAS_ID $DIR/$tfile failed"
20701
20702         chgrp $RUNAS_ID $DIR/$tfile ||
20703                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20704
20705         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20706         rm $DIR/$tfile || error "failed to remove released file"
20707 }
20708 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20709
20710 test_230a() {
20711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20713         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20714                 skip "Need MDS version at least 2.11.52"
20715
20716         local MDTIDX=1
20717
20718         test_mkdir $DIR/$tdir
20719         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20720         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20721         [ $mdt_idx -ne 0 ] &&
20722                 error "create local directory on wrong MDT $mdt_idx"
20723
20724         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20725                         error "create remote directory failed"
20726         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20727         [ $mdt_idx -ne $MDTIDX ] &&
20728                 error "create remote directory on wrong MDT $mdt_idx"
20729
20730         createmany -o $DIR/$tdir/test_230/t- 10 ||
20731                 error "create files on remote directory failed"
20732         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20733         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20734         rm -r $DIR/$tdir || error "unlink remote directory failed"
20735 }
20736 run_test 230a "Create remote directory and files under the remote directory"
20737
20738 test_230b() {
20739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20741         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20742                 skip "Need MDS version at least 2.11.52"
20743
20744         local MDTIDX=1
20745         local mdt_index
20746         local i
20747         local file
20748         local pid
20749         local stripe_count
20750         local migrate_dir=$DIR/$tdir/migrate_dir
20751         local other_dir=$DIR/$tdir/other_dir
20752
20753         test_mkdir $DIR/$tdir
20754         test_mkdir -i0 -c1 $migrate_dir
20755         test_mkdir -i0 -c1 $other_dir
20756         for ((i=0; i<10; i++)); do
20757                 mkdir -p $migrate_dir/dir_${i}
20758                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20759                         error "create files under remote dir failed $i"
20760         done
20761
20762         cp /etc/passwd $migrate_dir/$tfile
20763         cp /etc/passwd $other_dir/$tfile
20764         chattr +SAD $migrate_dir
20765         chattr +SAD $migrate_dir/$tfile
20766
20767         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20768         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20769         local old_dir_mode=$(stat -c%f $migrate_dir)
20770         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20771
20772         mkdir -p $migrate_dir/dir_default_stripe2
20773         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20774         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20775
20776         mkdir -p $other_dir
20777         ln $migrate_dir/$tfile $other_dir/luna
20778         ln $migrate_dir/$tfile $migrate_dir/sofia
20779         ln $other_dir/$tfile $migrate_dir/david
20780         ln -s $migrate_dir/$tfile $other_dir/zachary
20781         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20782         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20783
20784         local len
20785         local lnktgt
20786
20787         # inline symlink
20788         for len in 58 59 60; do
20789                 lnktgt=$(str_repeat 'l' $len)
20790                 touch $migrate_dir/$lnktgt
20791                 ln -s $lnktgt $migrate_dir/${len}char_ln
20792         done
20793
20794         # PATH_MAX
20795         for len in 4094 4095; do
20796                 lnktgt=$(str_repeat 'l' $len)
20797                 ln -s $lnktgt $migrate_dir/${len}char_ln
20798         done
20799
20800         # NAME_MAX
20801         for len in 254 255; do
20802                 touch $migrate_dir/$(str_repeat 'l' $len)
20803         done
20804
20805         $LFS migrate -m $MDTIDX $migrate_dir ||
20806                 error "fails on migrating remote dir to MDT1"
20807
20808         echo "migratate to MDT1, then checking.."
20809         for ((i = 0; i < 10; i++)); do
20810                 for file in $(find $migrate_dir/dir_${i}); do
20811                         mdt_index=$($LFS getstripe -m $file)
20812                         # broken symlink getstripe will fail
20813                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20814                                 error "$file is not on MDT${MDTIDX}"
20815                 done
20816         done
20817
20818         # the multiple link file should still in MDT0
20819         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20820         [ $mdt_index == 0 ] ||
20821                 error "$file is not on MDT${MDTIDX}"
20822
20823         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20824         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20825                 error " expect $old_dir_flag get $new_dir_flag"
20826
20827         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20828         [ "$old_file_flag" = "$new_file_flag" ] ||
20829                 error " expect $old_file_flag get $new_file_flag"
20830
20831         local new_dir_mode=$(stat -c%f $migrate_dir)
20832         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20833                 error "expect mode $old_dir_mode get $new_dir_mode"
20834
20835         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20836         [ "$old_file_mode" = "$new_file_mode" ] ||
20837                 error "expect mode $old_file_mode get $new_file_mode"
20838
20839         diff /etc/passwd $migrate_dir/$tfile ||
20840                 error "$tfile different after migration"
20841
20842         diff /etc/passwd $other_dir/luna ||
20843                 error "luna different after migration"
20844
20845         diff /etc/passwd $migrate_dir/sofia ||
20846                 error "sofia different after migration"
20847
20848         diff /etc/passwd $migrate_dir/david ||
20849                 error "david different after migration"
20850
20851         diff /etc/passwd $other_dir/zachary ||
20852                 error "zachary different after migration"
20853
20854         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20855                 error "${tfile}_ln different after migration"
20856
20857         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20858                 error "${tfile}_ln_other different after migration"
20859
20860         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20861         [ $stripe_count = 2 ] ||
20862                 error "dir strpe_count $d != 2 after migration."
20863
20864         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20865         [ $stripe_count = 2 ] ||
20866                 error "file strpe_count $d != 2 after migration."
20867
20868         #migrate back to MDT0
20869         MDTIDX=0
20870
20871         $LFS migrate -m $MDTIDX $migrate_dir ||
20872                 error "fails on migrating remote dir to MDT0"
20873
20874         echo "migrate back to MDT0, checking.."
20875         for file in $(find $migrate_dir); do
20876                 mdt_index=$($LFS getstripe -m $file)
20877                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20878                         error "$file is not on MDT${MDTIDX}"
20879         done
20880
20881         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20882         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20883                 error " expect $old_dir_flag get $new_dir_flag"
20884
20885         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20886         [ "$old_file_flag" = "$new_file_flag" ] ||
20887                 error " expect $old_file_flag get $new_file_flag"
20888
20889         local new_dir_mode=$(stat -c%f $migrate_dir)
20890         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20891                 error "expect mode $old_dir_mode get $new_dir_mode"
20892
20893         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20894         [ "$old_file_mode" = "$new_file_mode" ] ||
20895                 error "expect mode $old_file_mode get $new_file_mode"
20896
20897         diff /etc/passwd ${migrate_dir}/$tfile ||
20898                 error "$tfile different after migration"
20899
20900         diff /etc/passwd ${other_dir}/luna ||
20901                 error "luna different after migration"
20902
20903         diff /etc/passwd ${migrate_dir}/sofia ||
20904                 error "sofia different after migration"
20905
20906         diff /etc/passwd ${other_dir}/zachary ||
20907                 error "zachary different after migration"
20908
20909         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20910                 error "${tfile}_ln different after migration"
20911
20912         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20913                 error "${tfile}_ln_other different after migration"
20914
20915         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20916         [ $stripe_count = 2 ] ||
20917                 error "dir strpe_count $d != 2 after migration."
20918
20919         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20920         [ $stripe_count = 2 ] ||
20921                 error "file strpe_count $d != 2 after migration."
20922
20923         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20924 }
20925 run_test 230b "migrate directory"
20926
20927 test_230c() {
20928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20929         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20930         remote_mds_nodsh && skip "remote MDS with nodsh"
20931         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20932                 skip "Need MDS version at least 2.11.52"
20933
20934         local MDTIDX=1
20935         local total=3
20936         local mdt_index
20937         local file
20938         local migrate_dir=$DIR/$tdir/migrate_dir
20939
20940         #If migrating directory fails in the middle, all entries of
20941         #the directory is still accessiable.
20942         test_mkdir $DIR/$tdir
20943         test_mkdir -i0 -c1 $migrate_dir
20944         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20945         stat $migrate_dir
20946         createmany -o $migrate_dir/f $total ||
20947                 error "create files under ${migrate_dir} failed"
20948
20949         # fail after migrating top dir, and this will fail only once, so the
20950         # first sub file migration will fail (currently f3), others succeed.
20951         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20952         do_facet mds1 lctl set_param fail_loc=0x1801
20953         local t=$(ls $migrate_dir | wc -l)
20954         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20955                 error "migrate should fail"
20956         local u=$(ls $migrate_dir | wc -l)
20957         [ "$u" == "$t" ] || error "$u != $t during migration"
20958
20959         # add new dir/file should succeed
20960         mkdir $migrate_dir/dir ||
20961                 error "mkdir failed under migrating directory"
20962         touch $migrate_dir/file ||
20963                 error "create file failed under migrating directory"
20964
20965         # add file with existing name should fail
20966         for file in $migrate_dir/f*; do
20967                 stat $file > /dev/null || error "stat $file failed"
20968                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20969                         error "open(O_CREAT|O_EXCL) $file should fail"
20970                 $MULTIOP $file m && error "create $file should fail"
20971                 touch $DIR/$tdir/remote_dir/$tfile ||
20972                         error "touch $tfile failed"
20973                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20974                         error "link $file should fail"
20975                 mdt_index=$($LFS getstripe -m $file)
20976                 if [ $mdt_index == 0 ]; then
20977                         # file failed to migrate is not allowed to rename to
20978                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20979                                 error "rename to $file should fail"
20980                 else
20981                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20982                                 error "rename to $file failed"
20983                 fi
20984                 echo hello >> $file || error "write $file failed"
20985         done
20986
20987         # resume migration with different options should fail
20988         $LFS migrate -m 0 $migrate_dir &&
20989                 error "migrate -m 0 $migrate_dir should fail"
20990
20991         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20992                 error "migrate -c 2 $migrate_dir should fail"
20993
20994         # resume migration should succeed
20995         $LFS migrate -m $MDTIDX $migrate_dir ||
20996                 error "migrate $migrate_dir failed"
20997
20998         echo "Finish migration, then checking.."
20999         for file in $(find $migrate_dir); do
21000                 mdt_index=$($LFS getstripe -m $file)
21001                 [ $mdt_index == $MDTIDX ] ||
21002                         error "$file is not on MDT${MDTIDX}"
21003         done
21004
21005         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21006 }
21007 run_test 230c "check directory accessiblity if migration failed"
21008
21009 test_230d() {
21010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21012         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21013                 skip "Need MDS version at least 2.11.52"
21014         # LU-11235
21015         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21016
21017         local migrate_dir=$DIR/$tdir/migrate_dir
21018         local old_index
21019         local new_index
21020         local old_count
21021         local new_count
21022         local new_hash
21023         local mdt_index
21024         local i
21025         local j
21026
21027         old_index=$((RANDOM % MDSCOUNT))
21028         old_count=$((MDSCOUNT - old_index))
21029         new_index=$((RANDOM % MDSCOUNT))
21030         new_count=$((MDSCOUNT - new_index))
21031         new_hash=1 # for all_char
21032
21033         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21034         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21035
21036         test_mkdir $DIR/$tdir
21037         test_mkdir -i $old_index -c $old_count $migrate_dir
21038
21039         for ((i=0; i<100; i++)); do
21040                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21041                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21042                         error "create files under remote dir failed $i"
21043         done
21044
21045         echo -n "Migrate from MDT$old_index "
21046         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21047         echo -n "to MDT$new_index"
21048         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21049         echo
21050
21051         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21052         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21053                 error "migrate remote dir error"
21054
21055         echo "Finish migration, then checking.."
21056         for file in $(find $migrate_dir -maxdepth 1); do
21057                 mdt_index=$($LFS getstripe -m $file)
21058                 if [ $mdt_index -lt $new_index ] ||
21059                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21060                         error "$file is on MDT$mdt_index"
21061                 fi
21062         done
21063
21064         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21065 }
21066 run_test 230d "check migrate big directory"
21067
21068 test_230e() {
21069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21071         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21072                 skip "Need MDS version at least 2.11.52"
21073
21074         local i
21075         local j
21076         local a_fid
21077         local b_fid
21078
21079         mkdir_on_mdt0 $DIR/$tdir
21080         mkdir $DIR/$tdir/migrate_dir
21081         mkdir $DIR/$tdir/other_dir
21082         touch $DIR/$tdir/migrate_dir/a
21083         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21084         ls $DIR/$tdir/other_dir
21085
21086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21087                 error "migrate dir fails"
21088
21089         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21090         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21091
21092         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21093         [ $mdt_index == 0 ] || error "a is not on MDT0"
21094
21095         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21096                 error "migrate dir fails"
21097
21098         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21099         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21100
21101         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21102         [ $mdt_index == 1 ] || error "a is not on MDT1"
21103
21104         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21105         [ $mdt_index == 1 ] || error "b is not on MDT1"
21106
21107         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21108         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21109
21110         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21111
21112         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21113 }
21114 run_test 230e "migrate mulitple local link files"
21115
21116 test_230f() {
21117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21119         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21120                 skip "Need MDS version at least 2.11.52"
21121
21122         local a_fid
21123         local ln_fid
21124
21125         mkdir -p $DIR/$tdir
21126         mkdir $DIR/$tdir/migrate_dir
21127         $LFS mkdir -i1 $DIR/$tdir/other_dir
21128         touch $DIR/$tdir/migrate_dir/a
21129         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21130         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21131         ls $DIR/$tdir/other_dir
21132
21133         # a should be migrated to MDT1, since no other links on MDT0
21134         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21135                 error "#1 migrate dir fails"
21136         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21137         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21138         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21139         [ $mdt_index == 1 ] || error "a is not on MDT1"
21140
21141         # a should stay on MDT1, because it is a mulitple link file
21142         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21143                 error "#2 migrate dir fails"
21144         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21145         [ $mdt_index == 1 ] || error "a is not on MDT1"
21146
21147         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21148                 error "#3 migrate dir fails"
21149
21150         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21151         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21152         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21153
21154         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21155         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21156
21157         # a should be migrated to MDT0, since no other links on MDT1
21158         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21159                 error "#4 migrate dir fails"
21160         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21161         [ $mdt_index == 0 ] || error "a is not on MDT0"
21162
21163         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21164 }
21165 run_test 230f "migrate mulitple remote link files"
21166
21167 test_230g() {
21168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21170         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21171                 skip "Need MDS version at least 2.11.52"
21172
21173         mkdir -p $DIR/$tdir/migrate_dir
21174
21175         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21176                 error "migrating dir to non-exist MDT succeeds"
21177         true
21178 }
21179 run_test 230g "migrate dir to non-exist MDT"
21180
21181 test_230h() {
21182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21184         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21185                 skip "Need MDS version at least 2.11.52"
21186
21187         local mdt_index
21188
21189         mkdir -p $DIR/$tdir/migrate_dir
21190
21191         $LFS migrate -m1 $DIR &&
21192                 error "migrating mountpoint1 should fail"
21193
21194         $LFS migrate -m1 $DIR/$tdir/.. &&
21195                 error "migrating mountpoint2 should fail"
21196
21197         # same as mv
21198         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21199                 error "migrating $tdir/migrate_dir/.. should fail"
21200
21201         true
21202 }
21203 run_test 230h "migrate .. and root"
21204
21205 test_230i() {
21206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21207         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21208         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21209                 skip "Need MDS version at least 2.11.52"
21210
21211         mkdir -p $DIR/$tdir/migrate_dir
21212
21213         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21214                 error "migration fails with a tailing slash"
21215
21216         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21217                 error "migration fails with two tailing slashes"
21218 }
21219 run_test 230i "lfs migrate -m tolerates trailing slashes"
21220
21221 test_230j() {
21222         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21223         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21224                 skip "Need MDS version at least 2.11.52"
21225
21226         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21227         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21228                 error "create $tfile failed"
21229         cat /etc/passwd > $DIR/$tdir/$tfile
21230
21231         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21232
21233         cmp /etc/passwd $DIR/$tdir/$tfile ||
21234                 error "DoM file mismatch after migration"
21235 }
21236 run_test 230j "DoM file data not changed after dir migration"
21237
21238 test_230k() {
21239         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21240         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21241                 skip "Need MDS version at least 2.11.56"
21242
21243         local total=20
21244         local files_on_starting_mdt=0
21245
21246         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21247         $LFS getdirstripe $DIR/$tdir
21248         for i in $(seq $total); do
21249                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21250                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21251                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21252         done
21253
21254         echo "$files_on_starting_mdt files on MDT0"
21255
21256         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21257         $LFS getdirstripe $DIR/$tdir
21258
21259         files_on_starting_mdt=0
21260         for i in $(seq $total); do
21261                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21262                         error "file $tfile.$i mismatch after migration"
21263                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21264                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21265         done
21266
21267         echo "$files_on_starting_mdt files on MDT1 after migration"
21268         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21269
21270         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21271         $LFS getdirstripe $DIR/$tdir
21272
21273         files_on_starting_mdt=0
21274         for i in $(seq $total); do
21275                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21276                         error "file $tfile.$i mismatch after 2nd migration"
21277                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21278                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21279         done
21280
21281         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21282         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21283
21284         true
21285 }
21286 run_test 230k "file data not changed after dir migration"
21287
21288 test_230l() {
21289         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21290         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21291                 skip "Need MDS version at least 2.11.56"
21292
21293         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21294         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21295                 error "create files under remote dir failed $i"
21296         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21297 }
21298 run_test 230l "readdir between MDTs won't crash"
21299
21300 test_230m() {
21301         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21302         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21303                 skip "Need MDS version at least 2.11.56"
21304
21305         local MDTIDX=1
21306         local mig_dir=$DIR/$tdir/migrate_dir
21307         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21308         local shortstr="b"
21309         local val
21310
21311         echo "Creating files and dirs with xattrs"
21312         test_mkdir $DIR/$tdir
21313         test_mkdir -i0 -c1 $mig_dir
21314         mkdir $mig_dir/dir
21315         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21316                 error "cannot set xattr attr1 on dir"
21317         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21318                 error "cannot set xattr attr2 on dir"
21319         touch $mig_dir/dir/f0
21320         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21321                 error "cannot set xattr attr1 on file"
21322         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21323                 error "cannot set xattr attr2 on file"
21324         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21325         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21326         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21327         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21328         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21329         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21330         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21331         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21332         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21333
21334         echo "Migrating to MDT1"
21335         $LFS migrate -m $MDTIDX $mig_dir ||
21336                 error "fails on migrating dir to MDT1"
21337
21338         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21339         echo "Checking xattrs"
21340         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21341         [ "$val" = $longstr ] ||
21342                 error "expecting xattr1 $longstr on dir, found $val"
21343         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21344         [ "$val" = $shortstr ] ||
21345                 error "expecting xattr2 $shortstr on dir, found $val"
21346         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21347         [ "$val" = $longstr ] ||
21348                 error "expecting xattr1 $longstr on file, found $val"
21349         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21350         [ "$val" = $shortstr ] ||
21351                 error "expecting xattr2 $shortstr on file, found $val"
21352 }
21353 run_test 230m "xattrs not changed after dir migration"
21354
21355 test_230n() {
21356         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21357         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21358                 skip "Need MDS version at least 2.13.53"
21359
21360         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21361         cat /etc/hosts > $DIR/$tdir/$tfile
21362         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21363         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21364
21365         cmp /etc/hosts $DIR/$tdir/$tfile ||
21366                 error "File data mismatch after migration"
21367 }
21368 run_test 230n "Dir migration with mirrored file"
21369
21370 test_230o() {
21371         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21372         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21373                 skip "Need MDS version at least 2.13.52"
21374
21375         local mdts=$(comma_list $(mdts_nodes))
21376         local timeout=100
21377         local restripe_status
21378         local delta
21379         local i
21380
21381         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21382
21383         # in case "crush" hash type is not set
21384         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21385
21386         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21387                            mdt.*MDT0000.enable_dir_restripe)
21388         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21389         stack_trap "do_nodes $mdts $LCTL set_param \
21390                     mdt.*.enable_dir_restripe=$restripe_status"
21391
21392         mkdir $DIR/$tdir
21393         createmany -m $DIR/$tdir/f 100 ||
21394                 error "create files under remote dir failed $i"
21395         createmany -d $DIR/$tdir/d 100 ||
21396                 error "create dirs under remote dir failed $i"
21397
21398         for i in $(seq 2 $MDSCOUNT); do
21399                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21400                 $LFS setdirstripe -c $i $DIR/$tdir ||
21401                         error "split -c $i $tdir failed"
21402                 wait_update $HOSTNAME \
21403                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21404                         error "dir split not finished"
21405                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21406                         awk '/migrate/ {sum += $2} END { print sum }')
21407                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21408                 # delta is around total_files/stripe_count
21409                 (( $delta < 200 / (i - 1) + 4 )) ||
21410                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21411         done
21412 }
21413 run_test 230o "dir split"
21414
21415 test_230p() {
21416         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21417         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21418                 skip "Need MDS version at least 2.13.52"
21419
21420         local mdts=$(comma_list $(mdts_nodes))
21421         local timeout=100
21422         local restripe_status
21423         local delta
21424         local c
21425
21426         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21427
21428         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21429
21430         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21431                            mdt.*MDT0000.enable_dir_restripe)
21432         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21433         stack_trap "do_nodes $mdts $LCTL set_param \
21434                     mdt.*.enable_dir_restripe=$restripe_status"
21435
21436         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21437         createmany -m $DIR/$tdir/f 100 ||
21438                 error "create files under remote dir failed"
21439         createmany -d $DIR/$tdir/d 100 ||
21440                 error "create dirs under remote dir failed"
21441
21442         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21443                 local mdt_hash="crush"
21444
21445                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21446                 $LFS setdirstripe -c $c $DIR/$tdir ||
21447                         error "split -c $c $tdir failed"
21448                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21449                         mdt_hash="$mdt_hash,fixed"
21450                 elif [ $c -eq 1 ]; then
21451                         mdt_hash="none"
21452                 fi
21453                 wait_update $HOSTNAME \
21454                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21455                         error "dir merge not finished"
21456                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21457                         awk '/migrate/ {sum += $2} END { print sum }')
21458                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21459                 # delta is around total_files/stripe_count
21460                 (( delta < 200 / c + 4 )) ||
21461                         error "$delta files migrated >= $((200 / c + 4))"
21462         done
21463 }
21464 run_test 230p "dir merge"
21465
21466 test_230q() {
21467         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21468         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21469                 skip "Need MDS version at least 2.13.52"
21470
21471         local mdts=$(comma_list $(mdts_nodes))
21472         local saved_threshold=$(do_facet mds1 \
21473                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21474         local saved_delta=$(do_facet mds1 \
21475                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21476         local threshold=100
21477         local delta=2
21478         local total=0
21479         local stripe_count=0
21480         local stripe_index
21481         local nr_files
21482         local create
21483
21484         # test with fewer files on ZFS
21485         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21486
21487         stack_trap "do_nodes $mdts $LCTL set_param \
21488                     mdt.*.dir_split_count=$saved_threshold"
21489         stack_trap "do_nodes $mdts $LCTL set_param \
21490                     mdt.*.dir_split_delta=$saved_delta"
21491         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21492         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21493         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21494         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21495         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21496         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21497
21498         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21499         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21500
21501         create=$((threshold * 3 / 2))
21502         while [ $stripe_count -lt $MDSCOUNT ]; do
21503                 createmany -m $DIR/$tdir/f $total $create ||
21504                         error "create sub files failed"
21505                 stat $DIR/$tdir > /dev/null
21506                 total=$((total + create))
21507                 stripe_count=$((stripe_count + delta))
21508                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21509
21510                 wait_update $HOSTNAME \
21511                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21512                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21513
21514                 wait_update $HOSTNAME \
21515                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21516                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21517
21518                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21519                 echo "$nr_files/$total files on MDT$stripe_index after split"
21520                 # allow 10% margin of imbalance with crush hash
21521                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21522                         error "$nr_files files on MDT$stripe_index after split"
21523
21524                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21525                 [ $nr_files -eq $total ] ||
21526                         error "total sub files $nr_files != $total"
21527         done
21528
21529         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21530
21531         echo "fixed layout directory won't auto split"
21532         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21533         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21534                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21535         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21536                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21537 }
21538 run_test 230q "dir auto split"
21539
21540 test_230r() {
21541         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21542         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21543         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21544                 skip "Need MDS version at least 2.13.54"
21545
21546         # maximum amount of local locks:
21547         # parent striped dir - 2 locks
21548         # new stripe in parent to migrate to - 1 lock
21549         # source and target - 2 locks
21550         # Total 5 locks for regular file
21551         mkdir -p $DIR/$tdir
21552         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21553         touch $DIR/$tdir/dir1/eee
21554
21555         # create 4 hardlink for 4 more locks
21556         # Total: 9 locks > RS_MAX_LOCKS (8)
21557         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21558         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21559         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21560         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21561         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21562         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21563         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21564         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21565
21566         cancel_lru_locks mdc
21567
21568         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21569                 error "migrate dir fails"
21570
21571         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21572 }
21573 run_test 230r "migrate with too many local locks"
21574
21575 test_230s() {
21576         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21577                 skip "Need MDS version at least 2.14.52"
21578
21579         local mdts=$(comma_list $(mdts_nodes))
21580         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21581                                 mdt.*MDT0000.enable_dir_restripe)
21582
21583         stack_trap "do_nodes $mdts $LCTL set_param \
21584                     mdt.*.enable_dir_restripe=$restripe_status"
21585
21586         local st
21587         for st in 0 1; do
21588                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21589                 test_mkdir $DIR/$tdir
21590                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21591                         error "$LFS mkdir should return EEXIST if target exists"
21592                 rmdir $DIR/$tdir
21593         done
21594 }
21595 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21596
21597 test_230t()
21598 {
21599         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21600         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21601                 skip "Need MDS version at least 2.14.50"
21602
21603         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21604         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21605         $LFS project -p 1 -s $DIR/$tdir ||
21606                 error "set $tdir project id failed"
21607         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21608                 error "set subdir project id failed"
21609         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21610 }
21611 run_test 230t "migrate directory with project ID set"
21612
21613 test_230u()
21614 {
21615         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21616         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21617                 skip "Need MDS version at least 2.14.53"
21618
21619         local count
21620
21621         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21622         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21623         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21624         for i in $(seq 0 $((MDSCOUNT - 1))); do
21625                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21626                 echo "$count dirs migrated to MDT$i"
21627         done
21628         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21629         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21630 }
21631 run_test 230u "migrate directory by QOS"
21632
21633 test_230v()
21634 {
21635         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21636         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21637                 skip "Need MDS version at least 2.14.53"
21638
21639         local count
21640
21641         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21642         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21643         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21644         for i in $(seq 0 $((MDSCOUNT - 1))); do
21645                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21646                 echo "$count subdirs migrated to MDT$i"
21647                 (( i == 3 )) && (( count > 0 )) &&
21648                         error "subdir shouldn't be migrated to MDT3"
21649         done
21650         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21651         (( count == 3 )) || error "dirs migrated to $count MDTs"
21652 }
21653 run_test 230v "subdir migrated to the MDT where its parent is located"
21654
21655 test_230w() {
21656         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21657         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21658                 skip "Need MDS version at least 2.15.0"
21659
21660         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21661         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21662         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21663
21664         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21665                 error "migrate failed"
21666
21667         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21668                 error "$tdir stripe count mismatch"
21669
21670         for i in $(seq 0 9); do
21671                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21672                         error "d$i is striped"
21673         done
21674 }
21675 run_test 230w "non-recursive mode dir migration"
21676
21677 test_230x() {
21678         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21679         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21680                 skip "Need MDS version at least 2.15.0"
21681
21682         mkdir -p $DIR/$tdir || error "mkdir failed"
21683         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21684
21685         local mdt_name=$(mdtname_from_index 0)
21686         local low=$(do_facet mds2 $LCTL get_param -n \
21687                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21688         local high=$(do_facet mds2 $LCTL get_param -n \
21689                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21690         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21691         local maxage=$(do_facet mds2 $LCTL get_param -n \
21692                 osp.*$mdt_name-osp-MDT0001.maxage)
21693
21694         stack_trap "do_facet mds2 $LCTL set_param -n \
21695                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21696                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21697         stack_trap "do_facet mds2 $LCTL set_param -n \
21698                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21699
21700         do_facet mds2 $LCTL set_param -n \
21701                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21702         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21703         sleep 4
21704         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21705                 error "migrate $tdir should fail"
21706
21707         do_facet mds2 $LCTL set_param -n \
21708                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21709         do_facet mds2 $LCTL set_param -n \
21710                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21711         sleep 4
21712         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21713                 error "migrate failed"
21714         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21715                 error "$tdir stripe count mismatch"
21716 }
21717 run_test 230x "dir migration check space"
21718
21719 test_231a()
21720 {
21721         # For simplicity this test assumes that max_pages_per_rpc
21722         # is the same across all OSCs
21723         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21724         local bulk_size=$((max_pages * PAGE_SIZE))
21725         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21726                                        head -n 1)
21727
21728         mkdir -p $DIR/$tdir
21729         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21730                 error "failed to set stripe with -S ${brw_size}M option"
21731
21732         # clear the OSC stats
21733         $LCTL set_param osc.*.stats=0 &>/dev/null
21734         stop_writeback
21735
21736         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21737         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21738                 oflag=direct &>/dev/null || error "dd failed"
21739
21740         sync; sleep 1; sync # just to be safe
21741         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21742         if [ x$nrpcs != "x1" ]; then
21743                 $LCTL get_param osc.*.stats
21744                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21745         fi
21746
21747         start_writeback
21748         # Drop the OSC cache, otherwise we will read from it
21749         cancel_lru_locks osc
21750
21751         # clear the OSC stats
21752         $LCTL set_param osc.*.stats=0 &>/dev/null
21753
21754         # Client reads $bulk_size.
21755         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21756                 iflag=direct &>/dev/null || error "dd failed"
21757
21758         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21759         if [ x$nrpcs != "x1" ]; then
21760                 $LCTL get_param osc.*.stats
21761                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21762         fi
21763 }
21764 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21765
21766 test_231b() {
21767         mkdir -p $DIR/$tdir
21768         local i
21769         for i in {0..1023}; do
21770                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21771                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21772                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21773         done
21774         sync
21775 }
21776 run_test 231b "must not assert on fully utilized OST request buffer"
21777
21778 test_232a() {
21779         mkdir -p $DIR/$tdir
21780         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21781
21782         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21783         do_facet ost1 $LCTL set_param fail_loc=0x31c
21784
21785         # ignore dd failure
21786         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21787
21788         do_facet ost1 $LCTL set_param fail_loc=0
21789         umount_client $MOUNT || error "umount failed"
21790         mount_client $MOUNT || error "mount failed"
21791         stop ost1 || error "cannot stop ost1"
21792         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21793 }
21794 run_test 232a "failed lock should not block umount"
21795
21796 test_232b() {
21797         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21798                 skip "Need MDS version at least 2.10.58"
21799
21800         mkdir -p $DIR/$tdir
21801         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21802         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21803         sync
21804         cancel_lru_locks osc
21805
21806         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21807         do_facet ost1 $LCTL set_param fail_loc=0x31c
21808
21809         # ignore failure
21810         $LFS data_version $DIR/$tdir/$tfile || true
21811
21812         do_facet ost1 $LCTL set_param fail_loc=0
21813         umount_client $MOUNT || error "umount failed"
21814         mount_client $MOUNT || error "mount failed"
21815         stop ost1 || error "cannot stop ost1"
21816         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21817 }
21818 run_test 232b "failed data version lock should not block umount"
21819
21820 test_233a() {
21821         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21822                 skip "Need MDS version at least 2.3.64"
21823         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21824
21825         local fid=$($LFS path2fid $MOUNT)
21826
21827         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21828                 error "cannot access $MOUNT using its FID '$fid'"
21829 }
21830 run_test 233a "checking that OBF of the FS root succeeds"
21831
21832 test_233b() {
21833         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21834                 skip "Need MDS version at least 2.5.90"
21835         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21836
21837         local fid=$($LFS path2fid $MOUNT/.lustre)
21838
21839         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21840                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21841
21842         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21843         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21844                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21845 }
21846 run_test 233b "checking that OBF of the FS .lustre succeeds"
21847
21848 test_234() {
21849         local p="$TMP/sanityN-$TESTNAME.parameters"
21850         save_lustre_params client "llite.*.xattr_cache" > $p
21851         lctl set_param llite.*.xattr_cache 1 ||
21852                 skip_env "xattr cache is not supported"
21853
21854         mkdir -p $DIR/$tdir || error "mkdir failed"
21855         touch $DIR/$tdir/$tfile || error "touch failed"
21856         # OBD_FAIL_LLITE_XATTR_ENOMEM
21857         $LCTL set_param fail_loc=0x1405
21858         getfattr -n user.attr $DIR/$tdir/$tfile &&
21859                 error "getfattr should have failed with ENOMEM"
21860         $LCTL set_param fail_loc=0x0
21861         rm -rf $DIR/$tdir
21862
21863         restore_lustre_params < $p
21864         rm -f $p
21865 }
21866 run_test 234 "xattr cache should not crash on ENOMEM"
21867
21868 test_235() {
21869         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21870                 skip "Need MDS version at least 2.4.52"
21871
21872         flock_deadlock $DIR/$tfile
21873         local RC=$?
21874         case $RC in
21875                 0)
21876                 ;;
21877                 124) error "process hangs on a deadlock"
21878                 ;;
21879                 *) error "error executing flock_deadlock $DIR/$tfile"
21880                 ;;
21881         esac
21882 }
21883 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21884
21885 #LU-2935
21886 test_236() {
21887         check_swap_layouts_support
21888
21889         local ref1=/etc/passwd
21890         local ref2=/etc/group
21891         local file1=$DIR/$tdir/f1
21892         local file2=$DIR/$tdir/f2
21893
21894         test_mkdir -c1 $DIR/$tdir
21895         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21896         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21897         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21898         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21899         local fd=$(free_fd)
21900         local cmd="exec $fd<>$file2"
21901         eval $cmd
21902         rm $file2
21903         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21904                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21905         cmd="exec $fd>&-"
21906         eval $cmd
21907         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21908
21909         #cleanup
21910         rm -rf $DIR/$tdir
21911 }
21912 run_test 236 "Layout swap on open unlinked file"
21913
21914 # LU-4659 linkea consistency
21915 test_238() {
21916         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21917                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21918                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21919                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21920
21921         touch $DIR/$tfile
21922         ln $DIR/$tfile $DIR/$tfile.lnk
21923         touch $DIR/$tfile.new
21924         mv $DIR/$tfile.new $DIR/$tfile
21925         local fid1=$($LFS path2fid $DIR/$tfile)
21926         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21927         local path1=$($LFS fid2path $FSNAME "$fid1")
21928         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21929         local path2=$($LFS fid2path $FSNAME "$fid2")
21930         [ $tfile.lnk == $path2 ] ||
21931                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21932         rm -f $DIR/$tfile*
21933 }
21934 run_test 238 "Verify linkea consistency"
21935
21936 test_239A() { # was test_239
21937         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21938                 skip "Need MDS version at least 2.5.60"
21939
21940         local list=$(comma_list $(mdts_nodes))
21941
21942         mkdir -p $DIR/$tdir
21943         createmany -o $DIR/$tdir/f- 5000
21944         unlinkmany $DIR/$tdir/f- 5000
21945         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21946                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21947         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21948                         osp.*MDT*.sync_in_flight" | calc_sum)
21949         [ "$changes" -eq 0 ] || error "$changes not synced"
21950 }
21951 run_test 239A "osp_sync test"
21952
21953 test_239a() { #LU-5297
21954         remote_mds_nodsh && skip "remote MDS with nodsh"
21955
21956         touch $DIR/$tfile
21957         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21958         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21959         chgrp $RUNAS_GID $DIR/$tfile
21960         wait_delete_completed
21961 }
21962 run_test 239a "process invalid osp sync record correctly"
21963
21964 test_239b() { #LU-5297
21965         remote_mds_nodsh && skip "remote MDS with nodsh"
21966
21967         touch $DIR/$tfile1
21968         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21969         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21970         chgrp $RUNAS_GID $DIR/$tfile1
21971         wait_delete_completed
21972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21973         touch $DIR/$tfile2
21974         chgrp $RUNAS_GID $DIR/$tfile2
21975         wait_delete_completed
21976 }
21977 run_test 239b "process osp sync record with ENOMEM error correctly"
21978
21979 test_240() {
21980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21981         remote_mds_nodsh && skip "remote MDS with nodsh"
21982
21983         mkdir -p $DIR/$tdir
21984
21985         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21986                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21987         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21988                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21989
21990         umount_client $MOUNT || error "umount failed"
21991         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21992         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21993         mount_client $MOUNT || error "failed to mount client"
21994
21995         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21996         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21997 }
21998 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21999
22000 test_241_bio() {
22001         local count=$1
22002         local bsize=$2
22003
22004         for LOOP in $(seq $count); do
22005                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22006                 cancel_lru_locks $OSC || true
22007         done
22008 }
22009
22010 test_241_dio() {
22011         local count=$1
22012         local bsize=$2
22013
22014         for LOOP in $(seq $1); do
22015                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22016                         2>/dev/null
22017         done
22018 }
22019
22020 test_241a() { # was test_241
22021         local bsize=$PAGE_SIZE
22022
22023         (( bsize < 40960 )) && bsize=40960
22024         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22025         ls -la $DIR/$tfile
22026         cancel_lru_locks $OSC
22027         test_241_bio 1000 $bsize &
22028         PID=$!
22029         test_241_dio 1000 $bsize
22030         wait $PID
22031 }
22032 run_test 241a "bio vs dio"
22033
22034 test_241b() {
22035         local bsize=$PAGE_SIZE
22036
22037         (( bsize < 40960 )) && bsize=40960
22038         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22039         ls -la $DIR/$tfile
22040         test_241_dio 1000 $bsize &
22041         PID=$!
22042         test_241_dio 1000 $bsize
22043         wait $PID
22044 }
22045 run_test 241b "dio vs dio"
22046
22047 test_242() {
22048         remote_mds_nodsh && skip "remote MDS with nodsh"
22049
22050         mkdir_on_mdt0 $DIR/$tdir
22051         touch $DIR/$tdir/$tfile
22052
22053         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22054         do_facet mds1 lctl set_param fail_loc=0x105
22055         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22056
22057         do_facet mds1 lctl set_param fail_loc=0
22058         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22059 }
22060 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22061
22062 test_243()
22063 {
22064         test_mkdir $DIR/$tdir
22065         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22066 }
22067 run_test 243 "various group lock tests"
22068
22069 test_244a()
22070 {
22071         test_mkdir $DIR/$tdir
22072         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22073         sendfile_grouplock $DIR/$tdir/$tfile || \
22074                 error "sendfile+grouplock failed"
22075         rm -rf $DIR/$tdir
22076 }
22077 run_test 244a "sendfile with group lock tests"
22078
22079 test_244b()
22080 {
22081         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22082
22083         local threads=50
22084         local size=$((1024*1024))
22085
22086         test_mkdir $DIR/$tdir
22087         for i in $(seq 1 $threads); do
22088                 local file=$DIR/$tdir/file_$((i / 10))
22089                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22090                 local pids[$i]=$!
22091         done
22092         for i in $(seq 1 $threads); do
22093                 wait ${pids[$i]}
22094         done
22095 }
22096 run_test 244b "multi-threaded write with group lock"
22097
22098 test_245a() {
22099         local flagname="multi_mod_rpcs"
22100         local connect_data_name="max_mod_rpcs"
22101         local out
22102
22103         # check if multiple modify RPCs flag is set
22104         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22105                 grep "connect_flags:")
22106         echo "$out"
22107
22108         echo "$out" | grep -qw $flagname
22109         if [ $? -ne 0 ]; then
22110                 echo "connect flag $flagname is not set"
22111                 return
22112         fi
22113
22114         # check if multiple modify RPCs data is set
22115         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22116         echo "$out"
22117
22118         echo "$out" | grep -qw $connect_data_name ||
22119                 error "import should have connect data $connect_data_name"
22120 }
22121 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22122
22123 test_245b() {
22124         local flagname="multi_mod_rpcs"
22125         local connect_data_name="max_mod_rpcs"
22126         local out
22127
22128         remote_mds_nodsh && skip "remote MDS with nodsh"
22129         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22130
22131         # check if multiple modify RPCs flag is set
22132         out=$(do_facet mds1 \
22133               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22134               grep "connect_flags:")
22135         echo "$out"
22136
22137         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22138
22139         # check if multiple modify RPCs data is set
22140         out=$(do_facet mds1 \
22141               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22142
22143         [[ "$out" =~ $connect_data_name ]] ||
22144                 {
22145                         echo "$out"
22146                         error "missing connect data $connect_data_name"
22147                 }
22148 }
22149 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22150
22151 cleanup_247() {
22152         local submount=$1
22153
22154         trap 0
22155         umount_client $submount
22156         rmdir $submount
22157 }
22158
22159 test_247a() {
22160         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22161                 grep -q subtree ||
22162                 skip_env "Fileset feature is not supported"
22163
22164         local submount=${MOUNT}_$tdir
22165
22166         mkdir $MOUNT/$tdir
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         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22172         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22173                 error "read $MOUNT/$tdir/$tfile failed"
22174         cleanup_247 $submount
22175 }
22176 run_test 247a "mount subdir as fileset"
22177
22178 test_247b() {
22179         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22180                 skip_env "Fileset feature is not supported"
22181
22182         local submount=${MOUNT}_$tdir
22183
22184         rm -rf $MOUNT/$tdir
22185         mkdir -p $submount || error "mkdir $submount failed"
22186         SKIP_FILESET=1
22187         FILESET="$FILESET/$tdir" mount_client $submount &&
22188                 error "mount $submount should fail"
22189         rmdir $submount
22190 }
22191 run_test 247b "mount subdir that dose not exist"
22192
22193 test_247c() {
22194         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22195                 skip_env "Fileset feature is not supported"
22196
22197         local submount=${MOUNT}_$tdir
22198
22199         mkdir -p $MOUNT/$tdir/dir1
22200         mkdir -p $submount || error "mkdir $submount failed"
22201         trap "cleanup_247 $submount" EXIT
22202         FILESET="$FILESET/$tdir" mount_client $submount ||
22203                 error "mount $submount failed"
22204         local fid=$($LFS path2fid $MOUNT/)
22205         $LFS fid2path $submount $fid && error "fid2path should fail"
22206         cleanup_247 $submount
22207 }
22208 run_test 247c "running fid2path outside subdirectory root"
22209
22210 test_247d() {
22211         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22212                 skip "Fileset feature is not supported"
22213
22214         local submount=${MOUNT}_$tdir
22215
22216         mkdir -p $MOUNT/$tdir/dir1
22217         mkdir -p $submount || error "mkdir $submount failed"
22218         FILESET="$FILESET/$tdir" mount_client $submount ||
22219                 error "mount $submount failed"
22220         trap "cleanup_247 $submount" EXIT
22221
22222         local td=$submount/dir1
22223         local fid=$($LFS path2fid $td)
22224         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22225
22226         # check that we get the same pathname back
22227         local rootpath
22228         local found
22229         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22230                 echo "$rootpath $fid"
22231                 found=$($LFS fid2path $rootpath "$fid")
22232                 [ -n "$found" ] || error "fid2path should succeed"
22233                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22234         done
22235         # check wrong root path format
22236         rootpath=$submount"_wrong"
22237         found=$($LFS fid2path $rootpath "$fid")
22238         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22239
22240         cleanup_247 $submount
22241 }
22242 run_test 247d "running fid2path inside subdirectory root"
22243
22244 # LU-8037
22245 test_247e() {
22246         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22247                 grep -q subtree ||
22248                 skip "Fileset feature is not supported"
22249
22250         local submount=${MOUNT}_$tdir
22251
22252         mkdir $MOUNT/$tdir
22253         mkdir -p $submount || error "mkdir $submount failed"
22254         FILESET="$FILESET/.." mount_client $submount &&
22255                 error "mount $submount should fail"
22256         rmdir $submount
22257 }
22258 run_test 247e "mount .. as fileset"
22259
22260 test_247f() {
22261         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22262         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22263                 skip "Need at least version 2.14.50.162"
22264         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22265                 skip "Fileset feature is not supported"
22266
22267         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22268         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22269                 error "mkdir remote failed"
22270         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22271                 error "mkdir remote/subdir failed"
22272         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22273                 error "mkdir striped failed"
22274         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22275
22276         local submount=${MOUNT}_$tdir
22277
22278         mkdir -p $submount || error "mkdir $submount failed"
22279         stack_trap "rmdir $submount"
22280
22281         local dir
22282         local fileset=$FILESET
22283         local mdts=$(comma_list $(mdts_nodes))
22284
22285         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22286         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22287                 $tdir/striped/subdir $tdir/striped/.; do
22288                 FILESET="$fileset/$dir" mount_client $submount ||
22289                         error "mount $dir failed"
22290                 umount_client $submount
22291         done
22292 }
22293 run_test 247f "mount striped or remote directory as fileset"
22294
22295 test_subdir_mount_lock()
22296 {
22297         local testdir=$1
22298         local submount=${MOUNT}_$(basename $testdir)
22299
22300         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22301
22302         mkdir -p $submount || error "mkdir $submount failed"
22303         stack_trap "rmdir $submount"
22304
22305         FILESET="$fileset/$testdir" mount_client $submount ||
22306                 error "mount $FILESET failed"
22307         stack_trap "umount $submount"
22308
22309         local mdts=$(comma_list $(mdts_nodes))
22310
22311         local nrpcs
22312
22313         stat $submount > /dev/null || error "stat $submount failed"
22314         cancel_lru_locks $MDC
22315         stat $submount > /dev/null || error "stat $submount failed"
22316         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22317         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22318         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22319         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22320                 awk '/getattr/ {sum += $2} END {print sum}')
22321
22322         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22323 }
22324
22325 test_247g() {
22326         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22327
22328         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22329                 error "mkdir $tdir failed"
22330         test_subdir_mount_lock $tdir
22331 }
22332 run_test 247g "striped directory submount revalidate ROOT from cache"
22333
22334 test_247h() {
22335         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22336         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22337                 skip "Need MDS version at least 2.15.51"
22338
22339         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22340         test_subdir_mount_lock $tdir
22341         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22342         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22343                 error "mkdir $tdir.1 failed"
22344         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22345 }
22346 run_test 247h "remote directory submount revalidate ROOT from cache"
22347
22348 test_248a() {
22349         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22350         [ -z "$fast_read_sav" ] && skip "no fast read support"
22351
22352         # create a large file for fast read verification
22353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22354
22355         # make sure the file is created correctly
22356         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22357                 { rm -f $DIR/$tfile; skip "file creation error"; }
22358
22359         echo "Test 1: verify that fast read is 4 times faster on cache read"
22360
22361         # small read with fast read enabled
22362         $LCTL set_param -n llite.*.fast_read=1
22363         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22364                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22365                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22366         # small read with fast read disabled
22367         $LCTL set_param -n llite.*.fast_read=0
22368         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22369                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22370                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22371
22372         # verify that fast read is 4 times faster for cache read
22373         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22374                 error_not_in_vm "fast read was not 4 times faster: " \
22375                            "$t_fast vs $t_slow"
22376
22377         echo "Test 2: verify the performance between big and small read"
22378         $LCTL set_param -n llite.*.fast_read=1
22379
22380         # 1k non-cache read
22381         cancel_lru_locks osc
22382         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22383                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22384                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22385
22386         # 1M non-cache read
22387         cancel_lru_locks osc
22388         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22389                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22390                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22391
22392         # verify that big IO is not 4 times faster than small IO
22393         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22394                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22395
22396         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22397         rm -f $DIR/$tfile
22398 }
22399 run_test 248a "fast read verification"
22400
22401 test_248b() {
22402         # Default short_io_bytes=16384, try both smaller and larger sizes.
22403         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22404         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22405         echo "bs=53248 count=113 normal buffered write"
22406         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22407                 error "dd of initial data file failed"
22408         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22409
22410         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22411         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22412                 error "dd with sync normal writes failed"
22413         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22414
22415         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22416         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22417                 error "dd with sync small writes failed"
22418         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22419
22420         cancel_lru_locks osc
22421
22422         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22423         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22424         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22425         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22426                 iflag=direct || error "dd with O_DIRECT small read failed"
22427         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22428         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22429                 error "compare $TMP/$tfile.1 failed"
22430
22431         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22432         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22433
22434         # just to see what the maximum tunable value is, and test parsing
22435         echo "test invalid parameter 2MB"
22436         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22437                 error "too-large short_io_bytes allowed"
22438         echo "test maximum parameter 512KB"
22439         # if we can set a larger short_io_bytes, run test regardless of version
22440         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22441                 # older clients may not allow setting it this large, that's OK
22442                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22443                         skip "Need at least client version 2.13.50"
22444                 error "medium short_io_bytes failed"
22445         fi
22446         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22447         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22448
22449         echo "test large parameter 64KB"
22450         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22451         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22452
22453         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22454         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22455                 error "dd with sync large writes failed"
22456         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22457
22458         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22459         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22460         num=$((113 * 4096 / PAGE_SIZE))
22461         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22462         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22463                 error "dd with O_DIRECT large writes failed"
22464         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22465                 error "compare $DIR/$tfile.3 failed"
22466
22467         cancel_lru_locks osc
22468
22469         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22470         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22471                 error "dd with O_DIRECT large read failed"
22472         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22473                 error "compare $TMP/$tfile.2 failed"
22474
22475         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22476         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22477                 error "dd with O_DIRECT large read failed"
22478         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22479                 error "compare $TMP/$tfile.3 failed"
22480 }
22481 run_test 248b "test short_io read and write for both small and large sizes"
22482
22483 test_249() { # LU-7890
22484         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22485                 skip "Need at least version 2.8.54"
22486
22487         rm -f $DIR/$tfile
22488         $LFS setstripe -c 1 $DIR/$tfile
22489         # Offset 2T == 4k * 512M
22490         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22491                 error "dd to 2T offset failed"
22492 }
22493 run_test 249 "Write above 2T file size"
22494
22495 test_250() {
22496         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22497          && skip "no 16TB file size limit on ZFS"
22498
22499         $LFS setstripe -c 1 $DIR/$tfile
22500         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22501         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22502         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22503         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22504                 conv=notrunc,fsync && error "append succeeded"
22505         return 0
22506 }
22507 run_test 250 "Write above 16T limit"
22508
22509 test_251() {
22510         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22511
22512         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22513         #Skip once - writing the first stripe will succeed
22514         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22515         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22516                 error "short write happened"
22517
22518         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22519         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22520                 error "short read happened"
22521
22522         rm -f $DIR/$tfile
22523 }
22524 run_test 251 "Handling short read and write correctly"
22525
22526 test_252() {
22527         remote_mds_nodsh && skip "remote MDS with nodsh"
22528         remote_ost_nodsh && skip "remote OST with nodsh"
22529         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22530                 skip_env "ldiskfs only test"
22531         fi
22532
22533         local tgt
22534         local dev
22535         local out
22536         local uuid
22537         local num
22538         local gen
22539
22540         # check lr_reader on OST0000
22541         tgt=ost1
22542         dev=$(facet_device $tgt)
22543         out=$(do_facet $tgt $LR_READER $dev)
22544         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22545         echo "$out"
22546         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22547         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22548                 error "Invalid uuid returned by $LR_READER on target $tgt"
22549         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22550
22551         # check lr_reader -c on MDT0000
22552         tgt=mds1
22553         dev=$(facet_device $tgt)
22554         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22555                 skip "$LR_READER does not support additional options"
22556         fi
22557         out=$(do_facet $tgt $LR_READER -c $dev)
22558         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22559         echo "$out"
22560         num=$(echo "$out" | grep -c "mdtlov")
22561         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22562                 error "Invalid number of mdtlov clients returned by $LR_READER"
22563         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22564
22565         # check lr_reader -cr on MDT0000
22566         out=$(do_facet $tgt $LR_READER -cr $dev)
22567         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22568         echo "$out"
22569         echo "$out" | grep -q "^reply_data:$" ||
22570                 error "$LR_READER should have returned 'reply_data' section"
22571         num=$(echo "$out" | grep -c "client_generation")
22572         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22573 }
22574 run_test 252 "check lr_reader tool"
22575
22576 test_253() {
22577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22578         remote_mds_nodsh && skip "remote MDS with nodsh"
22579         remote_mgs_nodsh && skip "remote MGS with nodsh"
22580
22581         local ostidx=0
22582         local rc=0
22583         local ost_name=$(ostname_from_index $ostidx)
22584
22585         # on the mdt's osc
22586         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22587         do_facet $SINGLEMDS $LCTL get_param -n \
22588                 osp.$mdtosc_proc1.reserved_mb_high ||
22589                 skip  "remote MDS does not support reserved_mb_high"
22590
22591         rm -rf $DIR/$tdir
22592         wait_mds_ost_sync
22593         wait_delete_completed
22594         mkdir $DIR/$tdir
22595
22596         pool_add $TESTNAME || error "Pool creation failed"
22597         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22598
22599         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22600                 error "Setstripe failed"
22601
22602         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22603
22604         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22605                     grep "watermarks")
22606         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22607
22608         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22609                         osp.$mdtosc_proc1.prealloc_status)
22610         echo "prealloc_status $oa_status"
22611
22612         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22613                 error "File creation should fail"
22614
22615         #object allocation was stopped, but we still able to append files
22616         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22617                 oflag=append || error "Append failed"
22618
22619         rm -f $DIR/$tdir/$tfile.0
22620
22621         # For this test, we want to delete the files we created to go out of
22622         # space but leave the watermark, so we remain nearly out of space
22623         ost_watermarks_enospc_delete_files $tfile $ostidx
22624
22625         wait_delete_completed
22626
22627         sleep_maxage
22628
22629         for i in $(seq 10 12); do
22630                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22631                         2>/dev/null || error "File creation failed after rm"
22632         done
22633
22634         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22635                         osp.$mdtosc_proc1.prealloc_status)
22636         echo "prealloc_status $oa_status"
22637
22638         if (( oa_status != 0 )); then
22639                 error "Object allocation still disable after rm"
22640         fi
22641 }
22642 run_test 253 "Check object allocation limit"
22643
22644 test_254() {
22645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22646         remote_mds_nodsh && skip "remote MDS with nodsh"
22647
22648         local mdt=$(facet_svc $SINGLEMDS)
22649
22650         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22651                 skip "MDS does not support changelog_size"
22652
22653         local cl_user
22654
22655         changelog_register || error "changelog_register failed"
22656
22657         changelog_clear 0 || error "changelog_clear failed"
22658
22659         local size1=$(do_facet $SINGLEMDS \
22660                       $LCTL get_param -n mdd.$mdt.changelog_size)
22661         echo "Changelog size $size1"
22662
22663         rm -rf $DIR/$tdir
22664         $LFS mkdir -i 0 $DIR/$tdir
22665         # change something
22666         mkdir -p $DIR/$tdir/pics/2008/zachy
22667         touch $DIR/$tdir/pics/2008/zachy/timestamp
22668         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22669         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22670         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22671         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22672         rm $DIR/$tdir/pics/desktop.jpg
22673
22674         local size2=$(do_facet $SINGLEMDS \
22675                       $LCTL get_param -n mdd.$mdt.changelog_size)
22676         echo "Changelog size after work $size2"
22677
22678         (( $size2 > $size1 )) ||
22679                 error "new Changelog size=$size2 less than old size=$size1"
22680 }
22681 run_test 254 "Check changelog size"
22682
22683 ladvise_no_type()
22684 {
22685         local type=$1
22686         local file=$2
22687
22688         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22689                 awk -F: '{print $2}' | grep $type > /dev/null
22690         if [ $? -ne 0 ]; then
22691                 return 0
22692         fi
22693         return 1
22694 }
22695
22696 ladvise_no_ioctl()
22697 {
22698         local file=$1
22699
22700         lfs ladvise -a willread $file > /dev/null 2>&1
22701         if [ $? -eq 0 ]; then
22702                 return 1
22703         fi
22704
22705         lfs ladvise -a willread $file 2>&1 |
22706                 grep "Inappropriate ioctl for device" > /dev/null
22707         if [ $? -eq 0 ]; then
22708                 return 0
22709         fi
22710         return 1
22711 }
22712
22713 percent() {
22714         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22715 }
22716
22717 # run a random read IO workload
22718 # usage: random_read_iops <filename> <filesize> <iosize>
22719 random_read_iops() {
22720         local file=$1
22721         local fsize=$2
22722         local iosize=${3:-4096}
22723
22724         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22725                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22726 }
22727
22728 drop_file_oss_cache() {
22729         local file="$1"
22730         local nodes="$2"
22731
22732         $LFS ladvise -a dontneed $file 2>/dev/null ||
22733                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22734 }
22735
22736 ladvise_willread_performance()
22737 {
22738         local repeat=10
22739         local average_origin=0
22740         local average_cache=0
22741         local average_ladvise=0
22742
22743         for ((i = 1; i <= $repeat; i++)); do
22744                 echo "Iter $i/$repeat: reading without willread hint"
22745                 cancel_lru_locks osc
22746                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22747                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22748                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22749                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22750
22751                 cancel_lru_locks osc
22752                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22753                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22754                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22755
22756                 cancel_lru_locks osc
22757                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22758                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22759                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22760                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22761                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22762         done
22763         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22764         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22765         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22766
22767         speedup_cache=$(percent $average_cache $average_origin)
22768         speedup_ladvise=$(percent $average_ladvise $average_origin)
22769
22770         echo "Average uncached read: $average_origin"
22771         echo "Average speedup with OSS cached read: " \
22772                 "$average_cache = +$speedup_cache%"
22773         echo "Average speedup with ladvise willread: " \
22774                 "$average_ladvise = +$speedup_ladvise%"
22775
22776         local lowest_speedup=20
22777         if (( ${average_cache%.*} < $lowest_speedup )); then
22778                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22779                      " got $average_cache%. Skipping ladvise willread check."
22780                 return 0
22781         fi
22782
22783         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22784         # it is still good to run until then to exercise 'ladvise willread'
22785         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22786                 [ "$ost1_FSTYPE" = "zfs" ] &&
22787                 echo "osd-zfs does not support dontneed or drop_caches" &&
22788                 return 0
22789
22790         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22791         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22792                 error_not_in_vm "Speedup with willread is less than " \
22793                         "$lowest_speedup%, got $average_ladvise%"
22794 }
22795
22796 test_255a() {
22797         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22798                 skip "lustre < 2.8.54 does not support ladvise "
22799         remote_ost_nodsh && skip "remote OST with nodsh"
22800
22801         stack_trap "rm -f $DIR/$tfile"
22802         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22803
22804         ladvise_no_type willread $DIR/$tfile &&
22805                 skip "willread ladvise is not supported"
22806
22807         ladvise_no_ioctl $DIR/$tfile &&
22808                 skip "ladvise ioctl is not supported"
22809
22810         local size_mb=100
22811         local size=$((size_mb * 1048576))
22812         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22813                 error "dd to $DIR/$tfile failed"
22814
22815         lfs ladvise -a willread $DIR/$tfile ||
22816                 error "Ladvise failed with no range argument"
22817
22818         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22819                 error "Ladvise failed with no -l or -e argument"
22820
22821         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22822                 error "Ladvise failed with only -e argument"
22823
22824         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22825                 error "Ladvise failed with only -l argument"
22826
22827         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22828                 error "End offset should not be smaller than start offset"
22829
22830         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22831                 error "End offset should not be equal to start offset"
22832
22833         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22834                 error "Ladvise failed with overflowing -s argument"
22835
22836         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22837                 error "Ladvise failed with overflowing -e argument"
22838
22839         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22840                 error "Ladvise failed with overflowing -l argument"
22841
22842         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22843                 error "Ladvise succeeded with conflicting -l and -e arguments"
22844
22845         echo "Synchronous ladvise should wait"
22846         local delay=4
22847 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22848         do_nodes $(comma_list $(osts_nodes)) \
22849                 $LCTL set_param fail_val=$delay fail_loc=0x237
22850
22851         local start_ts=$SECONDS
22852         lfs ladvise -a willread $DIR/$tfile ||
22853                 error "Ladvise failed with no range argument"
22854         local end_ts=$SECONDS
22855         local inteval_ts=$((end_ts - start_ts))
22856
22857         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22858                 error "Synchronous advice didn't wait reply"
22859         fi
22860
22861         echo "Asynchronous ladvise shouldn't wait"
22862         local start_ts=$SECONDS
22863         lfs ladvise -a willread -b $DIR/$tfile ||
22864                 error "Ladvise failed with no range argument"
22865         local end_ts=$SECONDS
22866         local inteval_ts=$((end_ts - start_ts))
22867
22868         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22869                 error "Asynchronous advice blocked"
22870         fi
22871
22872         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22873         ladvise_willread_performance
22874 }
22875 run_test 255a "check 'lfs ladvise -a willread'"
22876
22877 facet_meminfo() {
22878         local facet=$1
22879         local info=$2
22880
22881         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22882 }
22883
22884 test_255b() {
22885         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22886                 skip "lustre < 2.8.54 does not support ladvise "
22887         remote_ost_nodsh && skip "remote OST with nodsh"
22888
22889         stack_trap "rm -f $DIR/$tfile"
22890         lfs setstripe -c 1 -i 0 $DIR/$tfile
22891
22892         ladvise_no_type dontneed $DIR/$tfile &&
22893                 skip "dontneed ladvise is not supported"
22894
22895         ladvise_no_ioctl $DIR/$tfile &&
22896                 skip "ladvise ioctl is not supported"
22897
22898         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22899                 [ "$ost1_FSTYPE" = "zfs" ] &&
22900                 skip "zfs-osd does not support 'ladvise dontneed'"
22901
22902         local size_mb=100
22903         local size=$((size_mb * 1048576))
22904         # In order to prevent disturbance of other processes, only check 3/4
22905         # of the memory usage
22906         local kibibytes=$((size_mb * 1024 * 3 / 4))
22907
22908         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22909                 error "dd to $DIR/$tfile failed"
22910
22911         #force write to complete before dropping OST cache & checking memory
22912         sync
22913
22914         local total=$(facet_meminfo ost1 MemTotal)
22915         echo "Total memory: $total KiB"
22916
22917         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22918         local before_read=$(facet_meminfo ost1 Cached)
22919         echo "Cache used before read: $before_read KiB"
22920
22921         lfs ladvise -a willread $DIR/$tfile ||
22922                 error "Ladvise willread failed"
22923         local after_read=$(facet_meminfo ost1 Cached)
22924         echo "Cache used after read: $after_read KiB"
22925
22926         lfs ladvise -a dontneed $DIR/$tfile ||
22927                 error "Ladvise dontneed again failed"
22928         local no_read=$(facet_meminfo ost1 Cached)
22929         echo "Cache used after dontneed ladvise: $no_read KiB"
22930
22931         if [ $total -lt $((before_read + kibibytes)) ]; then
22932                 echo "Memory is too small, abort checking"
22933                 return 0
22934         fi
22935
22936         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22937                 error "Ladvise willread should use more memory" \
22938                         "than $kibibytes KiB"
22939         fi
22940
22941         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22942                 error "Ladvise dontneed should release more memory" \
22943                         "than $kibibytes KiB"
22944         fi
22945 }
22946 run_test 255b "check 'lfs ladvise -a dontneed'"
22947
22948 test_255c() {
22949         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22950                 skip "lustre < 2.10.50 does not support lockahead"
22951
22952         local ost1_imp=$(get_osc_import_name client ost1)
22953         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22954                          cut -d'.' -f2)
22955         local count
22956         local new_count
22957         local difference
22958         local i
22959         local rc
22960
22961         test_mkdir -p $DIR/$tdir
22962         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22963
22964         #test 10 returns only success/failure
22965         i=10
22966         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22967         rc=$?
22968         if [ $rc -eq 255 ]; then
22969                 error "Ladvise test${i} failed, ${rc}"
22970         fi
22971
22972         #test 11 counts lock enqueue requests, all others count new locks
22973         i=11
22974         count=$(do_facet ost1 \
22975                 $LCTL get_param -n ost.OSS.ost.stats)
22976         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22977
22978         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22979         rc=$?
22980         if [ $rc -eq 255 ]; then
22981                 error "Ladvise test${i} failed, ${rc}"
22982         fi
22983
22984         new_count=$(do_facet ost1 \
22985                 $LCTL get_param -n ost.OSS.ost.stats)
22986         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22987                    awk '{ print $2 }')
22988
22989         difference="$((new_count - count))"
22990         if [ $difference -ne $rc ]; then
22991                 error "Ladvise test${i}, bad enqueue count, returned " \
22992                       "${rc}, actual ${difference}"
22993         fi
22994
22995         for i in $(seq 12 21); do
22996                 # If we do not do this, we run the risk of having too many
22997                 # locks and starting lock cancellation while we are checking
22998                 # lock counts.
22999                 cancel_lru_locks osc
23000
23001                 count=$($LCTL get_param -n \
23002                        ldlm.namespaces.$imp_name.lock_unused_count)
23003
23004                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23005                 rc=$?
23006                 if [ $rc -eq 255 ]; then
23007                         error "Ladvise test ${i} failed, ${rc}"
23008                 fi
23009
23010                 new_count=$($LCTL get_param -n \
23011                        ldlm.namespaces.$imp_name.lock_unused_count)
23012                 difference="$((new_count - count))"
23013
23014                 # Test 15 output is divided by 100 to map down to valid return
23015                 if [ $i -eq 15 ]; then
23016                         rc="$((rc * 100))"
23017                 fi
23018
23019                 if [ $difference -ne $rc ]; then
23020                         error "Ladvise test ${i}, bad lock count, returned " \
23021                               "${rc}, actual ${difference}"
23022                 fi
23023         done
23024
23025         #test 22 returns only success/failure
23026         i=22
23027         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23028         rc=$?
23029         if [ $rc -eq 255 ]; then
23030                 error "Ladvise test${i} failed, ${rc}"
23031         fi
23032 }
23033 run_test 255c "suite of ladvise lockahead tests"
23034
23035 test_256() {
23036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23037         remote_mds_nodsh && skip "remote MDS with nodsh"
23038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23039         changelog_users $SINGLEMDS | grep "^cl" &&
23040                 skip "active changelog user"
23041
23042         local cl_user
23043         local cat_sl
23044         local mdt_dev
23045
23046         mdt_dev=$(facet_device $SINGLEMDS)
23047         echo $mdt_dev
23048
23049         changelog_register || error "changelog_register failed"
23050
23051         rm -rf $DIR/$tdir
23052         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23053
23054         changelog_clear 0 || error "changelog_clear failed"
23055
23056         # change something
23057         touch $DIR/$tdir/{1..10}
23058
23059         # stop the MDT
23060         stop $SINGLEMDS || error "Fail to stop MDT"
23061
23062         # remount the MDT
23063         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23064                 error "Fail to start MDT"
23065
23066         #after mount new plainllog is used
23067         touch $DIR/$tdir/{11..19}
23068         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23069         stack_trap "rm -f $tmpfile"
23070         cat_sl=$(do_facet $SINGLEMDS "sync; \
23071                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23072                  llog_reader $tmpfile | grep -c type=1064553b")
23073         do_facet $SINGLEMDS llog_reader $tmpfile
23074
23075         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23076
23077         changelog_clear 0 || error "changelog_clear failed"
23078
23079         cat_sl=$(do_facet $SINGLEMDS "sync; \
23080                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23081                  llog_reader $tmpfile | grep -c type=1064553b")
23082
23083         if (( cat_sl == 2 )); then
23084                 error "Empty plain llog was not deleted from changelog catalog"
23085         elif (( cat_sl != 1 )); then
23086                 error "Active plain llog shouldn't be deleted from catalog"
23087         fi
23088 }
23089 run_test 256 "Check llog delete for empty and not full state"
23090
23091 test_257() {
23092         remote_mds_nodsh && skip "remote MDS with nodsh"
23093         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23094                 skip "Need MDS version at least 2.8.55"
23095
23096         test_mkdir $DIR/$tdir
23097
23098         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23099                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23100         stat $DIR/$tdir
23101
23102 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23103         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23104         local facet=mds$((mdtidx + 1))
23105         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23106         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23107
23108         stop $facet || error "stop MDS failed"
23109         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23110                 error "start MDS fail"
23111         wait_recovery_complete $facet
23112 }
23113 run_test 257 "xattr locks are not lost"
23114
23115 # Verify we take the i_mutex when security requires it
23116 test_258a() {
23117 #define OBD_FAIL_IMUTEX_SEC 0x141c
23118         $LCTL set_param fail_loc=0x141c
23119         touch $DIR/$tfile
23120         chmod u+s $DIR/$tfile
23121         chmod a+rwx $DIR/$tfile
23122         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23123         RC=$?
23124         if [ $RC -ne 0 ]; then
23125                 error "error, failed to take i_mutex, rc=$?"
23126         fi
23127         rm -f $DIR/$tfile
23128 }
23129 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23130
23131 # Verify we do NOT take the i_mutex in the normal case
23132 test_258b() {
23133 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23134         $LCTL set_param fail_loc=0x141d
23135         touch $DIR/$tfile
23136         chmod a+rwx $DIR
23137         chmod a+rw $DIR/$tfile
23138         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23139         RC=$?
23140         if [ $RC -ne 0 ]; then
23141                 error "error, took i_mutex unnecessarily, rc=$?"
23142         fi
23143         rm -f $DIR/$tfile
23144
23145 }
23146 run_test 258b "verify i_mutex security behavior"
23147
23148 test_259() {
23149         local file=$DIR/$tfile
23150         local before
23151         local after
23152
23153         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23154
23155         stack_trap "rm -f $file" EXIT
23156
23157         wait_delete_completed
23158         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23159         echo "before: $before"
23160
23161         $LFS setstripe -i 0 -c 1 $file
23162         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23163         sync_all_data
23164         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23165         echo "after write: $after"
23166
23167 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23168         do_facet ost1 $LCTL set_param fail_loc=0x2301
23169         $TRUNCATE $file 0
23170         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23171         echo "after truncate: $after"
23172
23173         stop ost1
23174         do_facet ost1 $LCTL set_param fail_loc=0
23175         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23176         sleep 2
23177         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23178         echo "after restart: $after"
23179         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23180                 error "missing truncate?"
23181
23182         return 0
23183 }
23184 run_test 259 "crash at delayed truncate"
23185
23186 test_260() {
23187 #define OBD_FAIL_MDC_CLOSE               0x806
23188         $LCTL set_param fail_loc=0x80000806
23189         touch $DIR/$tfile
23190
23191 }
23192 run_test 260 "Check mdc_close fail"
23193
23194 ### Data-on-MDT sanity tests ###
23195 test_270a() {
23196         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23197                 skip "Need MDS version at least 2.10.55 for DoM"
23198
23199         # create DoM file
23200         local dom=$DIR/$tdir/dom_file
23201         local tmp=$DIR/$tdir/tmp_file
23202
23203         mkdir_on_mdt0 $DIR/$tdir
23204
23205         # basic checks for DoM component creation
23206         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23207                 error "Can set MDT layout to non-first entry"
23208
23209         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23210                 error "Can define multiple entries as MDT layout"
23211
23212         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23213
23214         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23215         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23216         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23217
23218         local mdtidx=$($LFS getstripe -m $dom)
23219         local mdtname=MDT$(printf %04x $mdtidx)
23220         local facet=mds$((mdtidx + 1))
23221         local space_check=1
23222
23223         # Skip free space checks with ZFS
23224         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23225
23226         # write
23227         sync
23228         local size_tmp=$((65536 * 3))
23229         local mdtfree1=$(do_facet $facet \
23230                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23231
23232         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23233         # check also direct IO along write
23234         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23235         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23236         sync
23237         cmp $tmp $dom || error "file data is different"
23238         [ $(stat -c%s $dom) == $size_tmp ] ||
23239                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23240         if [ $space_check == 1 ]; then
23241                 local mdtfree2=$(do_facet $facet \
23242                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23243
23244                 # increase in usage from by $size_tmp
23245                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23246                         error "MDT free space wrong after write: " \
23247                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23248         fi
23249
23250         # truncate
23251         local size_dom=10000
23252
23253         $TRUNCATE $dom $size_dom
23254         [ $(stat -c%s $dom) == $size_dom ] ||
23255                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23256         if [ $space_check == 1 ]; then
23257                 mdtfree1=$(do_facet $facet \
23258                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23259                 # decrease in usage from $size_tmp to new $size_dom
23260                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23261                   $(((size_tmp - size_dom) / 1024)) ] ||
23262                         error "MDT free space is wrong after truncate: " \
23263                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23264         fi
23265
23266         # append
23267         cat $tmp >> $dom
23268         sync
23269         size_dom=$((size_dom + size_tmp))
23270         [ $(stat -c%s $dom) == $size_dom ] ||
23271                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23272         if [ $space_check == 1 ]; then
23273                 mdtfree2=$(do_facet $facet \
23274                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23275                 # increase in usage by $size_tmp from previous
23276                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23277                         error "MDT free space is wrong after append: " \
23278                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23279         fi
23280
23281         # delete
23282         rm $dom
23283         if [ $space_check == 1 ]; then
23284                 mdtfree1=$(do_facet $facet \
23285                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23286                 # decrease in usage by $size_dom from previous
23287                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23288                         error "MDT free space is wrong after removal: " \
23289                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23290         fi
23291
23292         # combined striping
23293         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23294                 error "Can't create DoM + OST striping"
23295
23296         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23297         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23298         # check also direct IO along write
23299         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23300         sync
23301         cmp $tmp $dom || error "file data is different"
23302         [ $(stat -c%s $dom) == $size_tmp ] ||
23303                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23304         rm $dom $tmp
23305
23306         return 0
23307 }
23308 run_test 270a "DoM: basic functionality tests"
23309
23310 test_270b() {
23311         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23312                 skip "Need MDS version at least 2.10.55"
23313
23314         local dom=$DIR/$tdir/dom_file
23315         local max_size=1048576
23316
23317         mkdir -p $DIR/$tdir
23318         $LFS setstripe -E $max_size -L mdt $dom
23319
23320         # truncate over the limit
23321         $TRUNCATE $dom $(($max_size + 1)) &&
23322                 error "successful truncate over the maximum size"
23323         # write over the limit
23324         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23325                 error "successful write over the maximum size"
23326         # append over the limit
23327         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23328         echo "12345" >> $dom && error "successful append over the maximum size"
23329         rm $dom
23330
23331         return 0
23332 }
23333 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23334
23335 test_270c() {
23336         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23337                 skip "Need MDS version at least 2.10.55"
23338
23339         mkdir -p $DIR/$tdir
23340         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23341
23342         # check files inherit DoM EA
23343         touch $DIR/$tdir/first
23344         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23345                 error "bad pattern"
23346         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23347                 error "bad stripe count"
23348         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23349                 error "bad stripe size"
23350
23351         # check directory inherits DoM EA and uses it as default
23352         mkdir $DIR/$tdir/subdir
23353         touch $DIR/$tdir/subdir/second
23354         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23355                 error "bad pattern in sub-directory"
23356         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23357                 error "bad stripe count in sub-directory"
23358         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23359                 error "bad stripe size in sub-directory"
23360         return 0
23361 }
23362 run_test 270c "DoM: DoM EA inheritance tests"
23363
23364 test_270d() {
23365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23366                 skip "Need MDS version at least 2.10.55"
23367
23368         mkdir -p $DIR/$tdir
23369         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23370
23371         # inherit default DoM striping
23372         mkdir $DIR/$tdir/subdir
23373         touch $DIR/$tdir/subdir/f1
23374
23375         # change default directory striping
23376         $LFS setstripe -c 1 $DIR/$tdir/subdir
23377         touch $DIR/$tdir/subdir/f2
23378         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23379                 error "wrong default striping in file 2"
23380         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23381                 error "bad pattern in file 2"
23382         return 0
23383 }
23384 run_test 270d "DoM: change striping from DoM to RAID0"
23385
23386 test_270e() {
23387         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23388                 skip "Need MDS version at least 2.10.55"
23389
23390         mkdir -p $DIR/$tdir/dom
23391         mkdir -p $DIR/$tdir/norm
23392         DOMFILES=20
23393         NORMFILES=10
23394         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23395         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23396
23397         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23398         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23399
23400         # find DoM files by layout
23401         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23402         [ $NUM -eq  $DOMFILES ] ||
23403                 error "lfs find -L: found $NUM, expected $DOMFILES"
23404         echo "Test 1: lfs find 20 DOM files by layout: OK"
23405
23406         # there should be 1 dir with default DOM striping
23407         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23408         [ $NUM -eq  1 ] ||
23409                 error "lfs find -L: found $NUM, expected 1 dir"
23410         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23411
23412         # find DoM files by stripe size
23413         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23414         [ $NUM -eq  $DOMFILES ] ||
23415                 error "lfs find -S: found $NUM, expected $DOMFILES"
23416         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23417
23418         # find files by stripe offset except DoM files
23419         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23420         [ $NUM -eq  $NORMFILES ] ||
23421                 error "lfs find -i: found $NUM, expected $NORMFILES"
23422         echo "Test 5: lfs find no DOM files by stripe index: OK"
23423         return 0
23424 }
23425 run_test 270e "DoM: lfs find with DoM files test"
23426
23427 test_270f() {
23428         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23429                 skip "Need MDS version at least 2.10.55"
23430
23431         local mdtname=${FSNAME}-MDT0000-mdtlov
23432         local dom=$DIR/$tdir/dom_file
23433         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23434                                                 lod.$mdtname.dom_stripesize)
23435         local dom_limit=131072
23436
23437         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23438         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23439                                                 lod.$mdtname.dom_stripesize)
23440         [ ${dom_limit} -eq ${dom_current} ] ||
23441                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23442
23443         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23444         $LFS setstripe -d $DIR/$tdir
23445         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23446                 error "Can't set directory default striping"
23447
23448         # exceed maximum stripe size
23449         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23450                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23451         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23452                 error "Able to create DoM component size more than LOD limit"
23453
23454         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23455         dom_current=$(do_facet mds1 $LCTL get_param -n \
23456                                                 lod.$mdtname.dom_stripesize)
23457         [ 0 -eq ${dom_current} ] ||
23458                 error "Can't set zero DoM stripe limit"
23459         rm $dom
23460
23461         # attempt to create DoM file on server with disabled DoM should
23462         # remove DoM entry from layout and be succeed
23463         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23464                 error "Can't create DoM file (DoM is disabled)"
23465         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23466                 error "File has DoM component while DoM is disabled"
23467         rm $dom
23468
23469         # attempt to create DoM file with only DoM stripe should return error
23470         $LFS setstripe -E $dom_limit -L mdt $dom &&
23471                 error "Able to create DoM-only file while DoM is disabled"
23472
23473         # too low values to be aligned with smallest stripe size 64K
23474         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23475         dom_current=$(do_facet mds1 $LCTL get_param -n \
23476                                                 lod.$mdtname.dom_stripesize)
23477         [ 30000 -eq ${dom_current} ] &&
23478                 error "Can set too small DoM stripe limit"
23479
23480         # 64K is a minimal stripe size in Lustre, expect limit of that size
23481         [ 65536 -eq ${dom_current} ] ||
23482                 error "Limit is not set to 64K but ${dom_current}"
23483
23484         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23485         dom_current=$(do_facet mds1 $LCTL get_param -n \
23486                                                 lod.$mdtname.dom_stripesize)
23487         echo $dom_current
23488         [ 2147483648 -eq ${dom_current} ] &&
23489                 error "Can set too large DoM stripe limit"
23490
23491         do_facet mds1 $LCTL set_param -n \
23492                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23493         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23494                 error "Can't create DoM component size after limit change"
23495         do_facet mds1 $LCTL set_param -n \
23496                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23497         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23498                 error "Can't create DoM file after limit decrease"
23499         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23500                 error "Can create big DoM component after limit decrease"
23501         touch ${dom}_def ||
23502                 error "Can't create file with old default layout"
23503
23504         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23505         return 0
23506 }
23507 run_test 270f "DoM: maximum DoM stripe size checks"
23508
23509 test_270g() {
23510         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23511                 skip "Need MDS version at least 2.13.52"
23512         local dom=$DIR/$tdir/$tfile
23513
23514         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23515         local lodname=${FSNAME}-MDT0000-mdtlov
23516
23517         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23518         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23519         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23520         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23521
23522         local dom_limit=1024
23523         local dom_threshold="50%"
23524
23525         $LFS setstripe -d $DIR/$tdir
23526         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23527                 error "Can't set directory default striping"
23528
23529         do_facet mds1 $LCTL set_param -n \
23530                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23531         # set 0 threshold and create DOM file to change tunable stripesize
23532         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23533         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23534                 error "Failed to create $dom file"
23535         # now tunable dom_cur_stripesize should reach maximum
23536         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23537                                         lod.${lodname}.dom_stripesize_cur_kb)
23538         [[ $dom_current == $dom_limit ]] ||
23539                 error "Current DOM stripesize is not maximum"
23540         rm $dom
23541
23542         # set threshold for further tests
23543         do_facet mds1 $LCTL set_param -n \
23544                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23545         echo "DOM threshold is $dom_threshold free space"
23546         local dom_def
23547         local dom_set
23548         # Spoof bfree to exceed threshold
23549         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23550         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23551         for spfree in 40 20 0 15 30 55; do
23552                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23553                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23554                         error "Failed to create $dom file"
23555                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23556                                         lod.${lodname}.dom_stripesize_cur_kb)
23557                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23558                 [[ $dom_def != $dom_current ]] ||
23559                         error "Default stripe size was not changed"
23560                 if (( spfree > 0 )) ; then
23561                         dom_set=$($LFS getstripe -S $dom)
23562                         (( dom_set == dom_def * 1024 )) ||
23563                                 error "DOM component size is still old"
23564                 else
23565                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23566                                 error "DoM component is set with no free space"
23567                 fi
23568                 rm $dom
23569                 dom_current=$dom_def
23570         done
23571 }
23572 run_test 270g "DoM: default DoM stripe size depends on free space"
23573
23574 test_270h() {
23575         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23576                 skip "Need MDS version at least 2.13.53"
23577
23578         local mdtname=${FSNAME}-MDT0000-mdtlov
23579         local dom=$DIR/$tdir/$tfile
23580         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23581
23582         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23583         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23584
23585         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23586         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23587                 error "can't create OST file"
23588         # mirrored file with DOM entry in the second mirror
23589         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23590                 error "can't create mirror with DoM component"
23591
23592         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23593
23594         # DOM component in the middle and has other enries in the same mirror,
23595         # should succeed but lost DoM component
23596         $LFS setstripe --copy=${dom}_1 $dom ||
23597                 error "Can't create file from OST|DOM mirror layout"
23598         # check new file has no DoM layout after all
23599         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23600                 error "File has DoM component while DoM is disabled"
23601 }
23602 run_test 270h "DoM: DoM stripe removal when disabled on server"
23603
23604 test_270i() {
23605         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23606                 skip "Need MDS version at least 2.14.54"
23607
23608         mkdir $DIR/$tdir
23609         # DoM with plain layout
23610         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23611                 error "default plain layout with DoM must fail"
23612         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23613                 error "setstripe plain file layout with DoM must fail"
23614         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23615                 error "default DoM layout with bad striping must fail"
23616         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23617                 error "setstripe to DoM layout with bad striping must fail"
23618         return 0
23619 }
23620 run_test 270i "DoM: setting invalid DoM striping should fail"
23621
23622 test_271a() {
23623         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23624                 skip "Need MDS version at least 2.10.55"
23625
23626         local dom=$DIR/$tdir/dom
23627
23628         mkdir -p $DIR/$tdir
23629
23630         $LFS setstripe -E 1024K -L mdt $dom
23631
23632         lctl set_param -n mdc.*.stats=clear
23633         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23634         cat $dom > /dev/null
23635         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23636         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23637         ls $dom
23638         rm -f $dom
23639 }
23640 run_test 271a "DoM: data is cached for read after write"
23641
23642 test_271b() {
23643         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23644                 skip "Need MDS version at least 2.10.55"
23645
23646         local dom=$DIR/$tdir/dom
23647
23648         mkdir -p $DIR/$tdir
23649
23650         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23651
23652         lctl set_param -n mdc.*.stats=clear
23653         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23654         cancel_lru_locks mdc
23655         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23656         # second stat to check size is cached on client
23657         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23658         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23659         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23660         rm -f $dom
23661 }
23662 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23663
23664 test_271ba() {
23665         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23666                 skip "Need MDS version at least 2.10.55"
23667
23668         local dom=$DIR/$tdir/dom
23669
23670         mkdir -p $DIR/$tdir
23671
23672         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23673
23674         lctl set_param -n mdc.*.stats=clear
23675         lctl set_param -n osc.*.stats=clear
23676         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23677         cancel_lru_locks mdc
23678         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23679         # second stat to check size is cached on client
23680         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23681         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23682         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23683         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23684         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23685         rm -f $dom
23686 }
23687 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23688
23689
23690 get_mdc_stats() {
23691         local mdtidx=$1
23692         local param=$2
23693         local mdt=MDT$(printf %04x $mdtidx)
23694
23695         if [ -z $param ]; then
23696                 lctl get_param -n mdc.*$mdt*.stats
23697         else
23698                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23699         fi
23700 }
23701
23702 test_271c() {
23703         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23704                 skip "Need MDS version at least 2.10.55"
23705
23706         local dom=$DIR/$tdir/dom
23707
23708         mkdir -p $DIR/$tdir
23709
23710         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23711
23712         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23713         local facet=mds$((mdtidx + 1))
23714
23715         cancel_lru_locks mdc
23716         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23717         createmany -o $dom 1000
23718         lctl set_param -n mdc.*.stats=clear
23719         smalliomany -w $dom 1000 200
23720         get_mdc_stats $mdtidx
23721         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23722         # Each file has 1 open, 1 IO enqueues, total 2000
23723         # but now we have also +1 getxattr for security.capability, total 3000
23724         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23725         unlinkmany $dom 1000
23726
23727         cancel_lru_locks mdc
23728         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23729         createmany -o $dom 1000
23730         lctl set_param -n mdc.*.stats=clear
23731         smalliomany -w $dom 1000 200
23732         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23733         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23734         # for OPEN and IO lock.
23735         [ $((enq - enq_2)) -ge 1000 ] ||
23736                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23737         unlinkmany $dom 1000
23738         return 0
23739 }
23740 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23741
23742 cleanup_271def_tests() {
23743         trap 0
23744         rm -f $1
23745 }
23746
23747 test_271d() {
23748         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23749                 skip "Need MDS version at least 2.10.57"
23750
23751         local dom=$DIR/$tdir/dom
23752         local tmp=$TMP/$tfile
23753         trap "cleanup_271def_tests $tmp" EXIT
23754
23755         mkdir -p $DIR/$tdir
23756
23757         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23758
23759         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23760
23761         cancel_lru_locks mdc
23762         dd if=/dev/urandom of=$tmp bs=1000 count=1
23763         dd if=$tmp of=$dom bs=1000 count=1
23764         cancel_lru_locks mdc
23765
23766         cat /etc/hosts >> $tmp
23767         lctl set_param -n mdc.*.stats=clear
23768
23769         # append data to the same file it should update local page
23770         echo "Append to the same page"
23771         cat /etc/hosts >> $dom
23772         local num=$(get_mdc_stats $mdtidx ost_read)
23773         local ra=$(get_mdc_stats $mdtidx req_active)
23774         local rw=$(get_mdc_stats $mdtidx req_waittime)
23775
23776         [ -z $num ] || error "$num READ RPC occured"
23777         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23778         echo "... DONE"
23779
23780         # compare content
23781         cmp $tmp $dom || error "file miscompare"
23782
23783         cancel_lru_locks mdc
23784         lctl set_param -n mdc.*.stats=clear
23785
23786         echo "Open and read file"
23787         cat $dom > /dev/null
23788         local num=$(get_mdc_stats $mdtidx ost_read)
23789         local ra=$(get_mdc_stats $mdtidx req_active)
23790         local rw=$(get_mdc_stats $mdtidx req_waittime)
23791
23792         [ -z $num ] || error "$num READ RPC occured"
23793         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23794         echo "... DONE"
23795
23796         # compare content
23797         cmp $tmp $dom || error "file miscompare"
23798
23799         return 0
23800 }
23801 run_test 271d "DoM: read on open (1K file in reply buffer)"
23802
23803 test_271f() {
23804         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23805                 skip "Need MDS version at least 2.10.57"
23806
23807         local dom=$DIR/$tdir/dom
23808         local tmp=$TMP/$tfile
23809         trap "cleanup_271def_tests $tmp" EXIT
23810
23811         mkdir -p $DIR/$tdir
23812
23813         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23814
23815         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23816
23817         cancel_lru_locks mdc
23818         dd if=/dev/urandom of=$tmp bs=265000 count=1
23819         dd if=$tmp of=$dom bs=265000 count=1
23820         cancel_lru_locks mdc
23821         cat /etc/hosts >> $tmp
23822         lctl set_param -n mdc.*.stats=clear
23823
23824         echo "Append to the same page"
23825         cat /etc/hosts >> $dom
23826         local num=$(get_mdc_stats $mdtidx ost_read)
23827         local ra=$(get_mdc_stats $mdtidx req_active)
23828         local rw=$(get_mdc_stats $mdtidx req_waittime)
23829
23830         [ -z $num ] || error "$num READ RPC occured"
23831         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23832         echo "... DONE"
23833
23834         # compare content
23835         cmp $tmp $dom || error "file miscompare"
23836
23837         cancel_lru_locks mdc
23838         lctl set_param -n mdc.*.stats=clear
23839
23840         echo "Open and read file"
23841         cat $dom > /dev/null
23842         local num=$(get_mdc_stats $mdtidx ost_read)
23843         local ra=$(get_mdc_stats $mdtidx req_active)
23844         local rw=$(get_mdc_stats $mdtidx req_waittime)
23845
23846         [ -z $num ] && num=0
23847         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23848         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23849         echo "... DONE"
23850
23851         # compare content
23852         cmp $tmp $dom || error "file miscompare"
23853
23854         return 0
23855 }
23856 run_test 271f "DoM: read on open (200K file and read tail)"
23857
23858 test_271g() {
23859         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23860                 skip "Skipping due to old client or server version"
23861
23862         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23863         # to get layout
23864         $CHECKSTAT -t file $DIR1/$tfile
23865
23866         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23867         MULTIOP_PID=$!
23868         sleep 1
23869         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23870         $LCTL set_param fail_loc=0x80000314
23871         rm $DIR1/$tfile || error "Unlink fails"
23872         RC=$?
23873         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23874         [ $RC -eq 0 ] || error "Failed write to stale object"
23875 }
23876 run_test 271g "Discard DoM data vs client flush race"
23877
23878 test_272a() {
23879         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23880                 skip "Need MDS version at least 2.11.50"
23881
23882         local dom=$DIR/$tdir/dom
23883         mkdir -p $DIR/$tdir
23884
23885         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23886         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23887                 error "failed to write data into $dom"
23888         local old_md5=$(md5sum $dom)
23889
23890         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23891                 error "failed to migrate to the same DoM component"
23892
23893         local new_md5=$(md5sum $dom)
23894
23895         [ "$old_md5" == "$new_md5" ] ||
23896                 error "md5sum differ: $old_md5, $new_md5"
23897
23898         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23899                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23900 }
23901 run_test 272a "DoM migration: new layout with the same DOM component"
23902
23903 test_272b() {
23904         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23905                 skip "Need MDS version at least 2.11.50"
23906
23907         local dom=$DIR/$tdir/dom
23908         mkdir -p $DIR/$tdir
23909         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23910
23911         local mdtidx=$($LFS getstripe -m $dom)
23912         local mdtname=MDT$(printf %04x $mdtidx)
23913         local facet=mds$((mdtidx + 1))
23914
23915         local mdtfree1=$(do_facet $facet \
23916                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23917         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23918                 error "failed to write data into $dom"
23919         local old_md5=$(md5sum $dom)
23920         cancel_lru_locks mdc
23921         local mdtfree1=$(do_facet $facet \
23922                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23923
23924         $LFS migrate -c2 $dom ||
23925                 error "failed to migrate to the new composite layout"
23926         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23927                 error "MDT stripe was not removed"
23928
23929         cancel_lru_locks mdc
23930         local new_md5=$(md5sum $dom)
23931         [ "$old_md5" == "$new_md5" ] ||
23932                 error "$old_md5 != $new_md5"
23933
23934         # Skip free space checks with ZFS
23935         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23936                 local mdtfree2=$(do_facet $facet \
23937                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23938                 [ $mdtfree2 -gt $mdtfree1 ] ||
23939                         error "MDT space is not freed after migration"
23940         fi
23941         return 0
23942 }
23943 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23944
23945 test_272c() {
23946         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23947                 skip "Need MDS version at least 2.11.50"
23948
23949         local dom=$DIR/$tdir/$tfile
23950         mkdir -p $DIR/$tdir
23951         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23952
23953         local mdtidx=$($LFS getstripe -m $dom)
23954         local mdtname=MDT$(printf %04x $mdtidx)
23955         local facet=mds$((mdtidx + 1))
23956
23957         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23958                 error "failed to write data into $dom"
23959         local old_md5=$(md5sum $dom)
23960         cancel_lru_locks mdc
23961         local mdtfree1=$(do_facet $facet \
23962                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23963
23964         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23965                 error "failed to migrate to the new composite layout"
23966         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23967                 error "MDT stripe was not removed"
23968
23969         cancel_lru_locks mdc
23970         local new_md5=$(md5sum $dom)
23971         [ "$old_md5" == "$new_md5" ] ||
23972                 error "$old_md5 != $new_md5"
23973
23974         # Skip free space checks with ZFS
23975         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23976                 local mdtfree2=$(do_facet $facet \
23977                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23978                 [ $mdtfree2 -gt $mdtfree1 ] ||
23979                         error "MDS space is not freed after migration"
23980         fi
23981         return 0
23982 }
23983 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23984
23985 test_272d() {
23986         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23987                 skip "Need MDS version at least 2.12.55"
23988
23989         local dom=$DIR/$tdir/$tfile
23990         mkdir -p $DIR/$tdir
23991         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23992
23993         local mdtidx=$($LFS getstripe -m $dom)
23994         local mdtname=MDT$(printf %04x $mdtidx)
23995         local facet=mds$((mdtidx + 1))
23996
23997         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23998                 error "failed to write data into $dom"
23999         local old_md5=$(md5sum $dom)
24000         cancel_lru_locks mdc
24001         local mdtfree1=$(do_facet $facet \
24002                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24003
24004         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24005                 error "failed mirroring to the new composite layout"
24006         $LFS mirror resync $dom ||
24007                 error "failed mirror resync"
24008         $LFS mirror split --mirror-id 1 -d $dom ||
24009                 error "failed mirror split"
24010
24011         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24012                 error "MDT stripe was not removed"
24013
24014         cancel_lru_locks mdc
24015         local new_md5=$(md5sum $dom)
24016         [ "$old_md5" == "$new_md5" ] ||
24017                 error "$old_md5 != $new_md5"
24018
24019         # Skip free space checks with ZFS
24020         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24021                 local mdtfree2=$(do_facet $facet \
24022                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24023                 [ $mdtfree2 -gt $mdtfree1 ] ||
24024                         error "MDS space is not freed after DOM mirror deletion"
24025         fi
24026         return 0
24027 }
24028 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24029
24030 test_272e() {
24031         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24032                 skip "Need MDS version at least 2.12.55"
24033
24034         local dom=$DIR/$tdir/$tfile
24035         mkdir -p $DIR/$tdir
24036         $LFS setstripe -c 2 $dom
24037
24038         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24039                 error "failed to write data into $dom"
24040         local old_md5=$(md5sum $dom)
24041         cancel_lru_locks
24042
24043         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24044                 error "failed mirroring to the DOM layout"
24045         $LFS mirror resync $dom ||
24046                 error "failed mirror resync"
24047         $LFS mirror split --mirror-id 1 -d $dom ||
24048                 error "failed mirror split"
24049
24050         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24051                 error "MDT stripe wasn't set"
24052
24053         cancel_lru_locks
24054         local new_md5=$(md5sum $dom)
24055         [ "$old_md5" == "$new_md5" ] ||
24056                 error "$old_md5 != $new_md5"
24057
24058         return 0
24059 }
24060 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24061
24062 test_272f() {
24063         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24064                 skip "Need MDS version at least 2.12.55"
24065
24066         local dom=$DIR/$tdir/$tfile
24067         mkdir -p $DIR/$tdir
24068         $LFS setstripe -c 2 $dom
24069
24070         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24071                 error "failed to write data into $dom"
24072         local old_md5=$(md5sum $dom)
24073         cancel_lru_locks
24074
24075         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24076                 error "failed migrating to the DOM file"
24077
24078         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24079                 error "MDT stripe wasn't set"
24080
24081         cancel_lru_locks
24082         local new_md5=$(md5sum $dom)
24083         [ "$old_md5" != "$new_md5" ] &&
24084                 error "$old_md5 != $new_md5"
24085
24086         return 0
24087 }
24088 run_test 272f "DoM migration: OST-striped file to DOM file"
24089
24090 test_273a() {
24091         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24092                 skip "Need MDS version at least 2.11.50"
24093
24094         # Layout swap cannot be done if either file has DOM component,
24095         # this will never be supported, migration should be used instead
24096
24097         local dom=$DIR/$tdir/$tfile
24098         mkdir -p $DIR/$tdir
24099
24100         $LFS setstripe -c2 ${dom}_plain
24101         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24102         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24103                 error "can swap layout with DoM component"
24104         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24105                 error "can swap layout with DoM component"
24106
24107         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24108         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24109                 error "can swap layout with DoM component"
24110         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24111                 error "can swap layout with DoM component"
24112         return 0
24113 }
24114 run_test 273a "DoM: layout swapping should fail with DOM"
24115
24116 test_273b() {
24117         mkdir -p $DIR/$tdir
24118         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24119
24120 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24121         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24122
24123         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24124 }
24125 run_test 273b "DoM: race writeback and object destroy"
24126
24127 test_273c() {
24128         mkdir -p $DIR/$tdir
24129         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24130
24131         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24132         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24133
24134         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24135 }
24136 run_test 273c "race writeback and object destroy"
24137
24138 test_275() {
24139         remote_ost_nodsh && skip "remote OST with nodsh"
24140         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24141                 skip "Need OST version >= 2.10.57"
24142
24143         local file=$DIR/$tfile
24144         local oss
24145
24146         oss=$(comma_list $(osts_nodes))
24147
24148         dd if=/dev/urandom of=$file bs=1M count=2 ||
24149                 error "failed to create a file"
24150         cancel_lru_locks osc
24151
24152         #lock 1
24153         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24154                 error "failed to read a file"
24155
24156 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24157         $LCTL set_param fail_loc=0x8000031f
24158
24159         cancel_lru_locks osc &
24160         sleep 1
24161
24162 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24163         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24164         #IO takes another lock, but matches the PENDING one
24165         #and places it to the IO RPC
24166         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24167                 error "failed to read a file with PENDING lock"
24168 }
24169 run_test 275 "Read on a canceled duplicate lock"
24170
24171 test_276() {
24172         remote_ost_nodsh && skip "remote OST with nodsh"
24173         local pid
24174
24175         do_facet ost1 "(while true; do \
24176                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24177                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24178         pid=$!
24179
24180         for LOOP in $(seq 20); do
24181                 stop ost1
24182                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24183         done
24184         kill -9 $pid
24185         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24186                 rm $TMP/sanity_276_pid"
24187 }
24188 run_test 276 "Race between mount and obd_statfs"
24189
24190 test_277() {
24191         $LCTL set_param ldlm.namespaces.*.lru_size=0
24192         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24193         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24194                         grep ^used_mb | awk '{print $2}')
24195         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24196         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24197                 oflag=direct conv=notrunc
24198         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24199                         grep ^used_mb | awk '{print $2}')
24200         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24201 }
24202 run_test 277 "Direct IO shall drop page cache"
24203
24204 test_278() {
24205         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24206         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24207         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24208                 skip "needs the same host for mdt1 mdt2" && return
24209
24210         local pid1
24211         local pid2
24212
24213 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24214         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24215         stop mds2 &
24216         pid2=$!
24217
24218         stop mds1
24219
24220         echo "Starting MDTs"
24221         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24222         wait $pid2
24223 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24224 #will return NULL
24225         do_facet mds2 $LCTL set_param fail_loc=0
24226
24227         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24228         wait_recovery_complete mds2
24229 }
24230 run_test 278 "Race starting MDS between MDTs stop/start"
24231
24232 test_280() {
24233         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24234                 skip "Need MGS version at least 2.13.52"
24235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24236         combined_mgs_mds || skip "needs combined MGS/MDT"
24237
24238         umount_client $MOUNT
24239 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24240         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24241
24242         mount_client $MOUNT &
24243         sleep 1
24244         stop mgs || error "stop mgs failed"
24245         #for a race mgs would crash
24246         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24247         # make sure we unmount client before remounting
24248         wait
24249         umount_client $MOUNT
24250         mount_client $MOUNT || error "mount client failed"
24251 }
24252 run_test 280 "Race between MGS umount and client llog processing"
24253
24254 cleanup_test_300() {
24255         trap 0
24256         umask $SAVE_UMASK
24257 }
24258 test_striped_dir() {
24259         local mdt_index=$1
24260         local stripe_count
24261         local stripe_index
24262
24263         mkdir -p $DIR/$tdir
24264
24265         SAVE_UMASK=$(umask)
24266         trap cleanup_test_300 RETURN EXIT
24267
24268         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24269                                                 $DIR/$tdir/striped_dir ||
24270                 error "set striped dir error"
24271
24272         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24273         [ "$mode" = "755" ] || error "expect 755 got $mode"
24274
24275         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24276                 error "getdirstripe failed"
24277         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24278         if [ "$stripe_count" != "2" ]; then
24279                 error "1:stripe_count is $stripe_count, expect 2"
24280         fi
24281         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24282         if [ "$stripe_count" != "2" ]; then
24283                 error "2:stripe_count is $stripe_count, expect 2"
24284         fi
24285
24286         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24287         if [ "$stripe_index" != "$mdt_index" ]; then
24288                 error "stripe_index is $stripe_index, expect $mdt_index"
24289         fi
24290
24291         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24292                 error "nlink error after create striped dir"
24293
24294         mkdir $DIR/$tdir/striped_dir/a
24295         mkdir $DIR/$tdir/striped_dir/b
24296
24297         stat $DIR/$tdir/striped_dir/a ||
24298                 error "create dir under striped dir failed"
24299         stat $DIR/$tdir/striped_dir/b ||
24300                 error "create dir under striped dir failed"
24301
24302         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24303                 error "nlink error after mkdir"
24304
24305         rmdir $DIR/$tdir/striped_dir/a
24306         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24307                 error "nlink error after rmdir"
24308
24309         rmdir $DIR/$tdir/striped_dir/b
24310         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24311                 error "nlink error after rmdir"
24312
24313         chattr +i $DIR/$tdir/striped_dir
24314         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24315                 error "immutable flags not working under striped dir!"
24316         chattr -i $DIR/$tdir/striped_dir
24317
24318         rmdir $DIR/$tdir/striped_dir ||
24319                 error "rmdir striped dir error"
24320
24321         cleanup_test_300
24322
24323         true
24324 }
24325
24326 test_300a() {
24327         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24328                 skip "skipped for lustre < 2.7.0"
24329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24331
24332         test_striped_dir 0 || error "failed on striped dir on MDT0"
24333         test_striped_dir 1 || error "failed on striped dir on MDT0"
24334 }
24335 run_test 300a "basic striped dir sanity test"
24336
24337 test_300b() {
24338         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24339                 skip "skipped for lustre < 2.7.0"
24340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24341         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24342
24343         local i
24344         local mtime1
24345         local mtime2
24346         local mtime3
24347
24348         test_mkdir $DIR/$tdir || error "mkdir fail"
24349         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24350                 error "set striped dir error"
24351         for i in {0..9}; do
24352                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24353                 sleep 1
24354                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24355                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24356                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24357                 sleep 1
24358                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24359                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24360                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24361         done
24362         true
24363 }
24364 run_test 300b "check ctime/mtime for striped dir"
24365
24366 test_300c() {
24367         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24368                 skip "skipped for lustre < 2.7.0"
24369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24371
24372         local file_count
24373
24374         mkdir_on_mdt0 $DIR/$tdir
24375         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24376                 error "set striped dir error"
24377
24378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24379                 error "chown striped dir failed"
24380
24381         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24382                 error "create 5k files failed"
24383
24384         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24385
24386         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24387
24388         rm -rf $DIR/$tdir
24389 }
24390 run_test 300c "chown && check ls under striped directory"
24391
24392 test_300d() {
24393         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24394                 skip "skipped for lustre < 2.7.0"
24395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24397
24398         local stripe_count
24399         local file
24400
24401         mkdir -p $DIR/$tdir
24402         $LFS setstripe -c 2 $DIR/$tdir
24403
24404         #local striped directory
24405         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24406                 error "set striped dir error"
24407         #look at the directories for debug purposes
24408         ls -l $DIR/$tdir
24409         $LFS getdirstripe $DIR/$tdir
24410         ls -l $DIR/$tdir/striped_dir
24411         $LFS getdirstripe $DIR/$tdir/striped_dir
24412         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24413                 error "create 10 files failed"
24414
24415         #remote striped directory
24416         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24417                 error "set striped dir error"
24418         #look at the directories for debug purposes
24419         ls -l $DIR/$tdir
24420         $LFS getdirstripe $DIR/$tdir
24421         ls -l $DIR/$tdir/remote_striped_dir
24422         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24423         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24424                 error "create 10 files failed"
24425
24426         for file in $(find $DIR/$tdir); do
24427                 stripe_count=$($LFS getstripe -c $file)
24428                 [ $stripe_count -eq 2 ] ||
24429                         error "wrong stripe $stripe_count for $file"
24430         done
24431
24432         rm -rf $DIR/$tdir
24433 }
24434 run_test 300d "check default stripe under striped directory"
24435
24436 test_300e() {
24437         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24438                 skip "Need MDS version at least 2.7.55"
24439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24441
24442         local stripe_count
24443         local file
24444
24445         mkdir -p $DIR/$tdir
24446
24447         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24448                 error "set striped dir error"
24449
24450         touch $DIR/$tdir/striped_dir/a
24451         touch $DIR/$tdir/striped_dir/b
24452         touch $DIR/$tdir/striped_dir/c
24453
24454         mkdir $DIR/$tdir/striped_dir/dir_a
24455         mkdir $DIR/$tdir/striped_dir/dir_b
24456         mkdir $DIR/$tdir/striped_dir/dir_c
24457
24458         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24459                 error "set striped adir under striped dir error"
24460
24461         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24462                 error "set striped bdir under striped dir error"
24463
24464         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24465                 error "set striped cdir under striped dir error"
24466
24467         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24468                 error "rename dir under striped dir fails"
24469
24470         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24471                 error "rename dir under different stripes fails"
24472
24473         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24474                 error "rename file under striped dir should succeed"
24475
24476         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24477                 error "rename dir under striped dir should succeed"
24478
24479         rm -rf $DIR/$tdir
24480 }
24481 run_test 300e "check rename under striped directory"
24482
24483 test_300f() {
24484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24486         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24487                 skip "Need MDS version at least 2.7.55"
24488
24489         local stripe_count
24490         local file
24491
24492         rm -rf $DIR/$tdir
24493         mkdir -p $DIR/$tdir
24494
24495         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24496                 error "set striped dir error"
24497
24498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24499                 error "set striped dir error"
24500
24501         touch $DIR/$tdir/striped_dir/a
24502         mkdir $DIR/$tdir/striped_dir/dir_a
24503         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24504                 error "create striped dir under striped dir fails"
24505
24506         touch $DIR/$tdir/striped_dir1/b
24507         mkdir $DIR/$tdir/striped_dir1/dir_b
24508         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24509                 error "create striped dir under striped dir fails"
24510
24511         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24512                 error "rename dir under different striped dir should fail"
24513
24514         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24515                 error "rename striped dir under diff striped dir should fail"
24516
24517         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24518                 error "rename file under diff striped dirs fails"
24519
24520         rm -rf $DIR/$tdir
24521 }
24522 run_test 300f "check rename cross striped directory"
24523
24524 test_300_check_default_striped_dir()
24525 {
24526         local dirname=$1
24527         local default_count=$2
24528         local default_index=$3
24529         local stripe_count
24530         local stripe_index
24531         local dir_stripe_index
24532         local dir
24533
24534         echo "checking $dirname $default_count $default_index"
24535         $LFS setdirstripe -D -c $default_count -i $default_index \
24536                                 -H all_char $DIR/$tdir/$dirname ||
24537                 error "set default stripe on striped dir error"
24538         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24539         [ $stripe_count -eq $default_count ] ||
24540                 error "expect $default_count get $stripe_count for $dirname"
24541
24542         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24543         [ $stripe_index -eq $default_index ] ||
24544                 error "expect $default_index get $stripe_index for $dirname"
24545
24546         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24547                                                 error "create dirs failed"
24548
24549         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24550         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24551         for dir in $(find $DIR/$tdir/$dirname/*); do
24552                 stripe_count=$($LFS getdirstripe -c $dir)
24553                 (( $stripe_count == $default_count )) ||
24554                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24555                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24556                 error "stripe count $default_count != $stripe_count for $dir"
24557
24558                 stripe_index=$($LFS getdirstripe -i $dir)
24559                 [ $default_index -eq -1 ] ||
24560                         [ $stripe_index -eq $default_index ] ||
24561                         error "$stripe_index != $default_index for $dir"
24562
24563                 #check default stripe
24564                 stripe_count=$($LFS getdirstripe -D -c $dir)
24565                 [ $stripe_count -eq $default_count ] ||
24566                 error "default count $default_count != $stripe_count for $dir"
24567
24568                 stripe_index=$($LFS getdirstripe -D -i $dir)
24569                 [ $stripe_index -eq $default_index ] ||
24570                 error "default index $default_index != $stripe_index for $dir"
24571         done
24572         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24573 }
24574
24575 test_300g() {
24576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24577         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24578                 skip "Need MDS version at least 2.7.55"
24579
24580         local dir
24581         local stripe_count
24582         local stripe_index
24583
24584         mkdir_on_mdt0 $DIR/$tdir
24585         mkdir $DIR/$tdir/normal_dir
24586
24587         #Checking when client cache stripe index
24588         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24589         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24590                 error "create striped_dir failed"
24591
24592         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24593                 error "create dir0 fails"
24594         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24595         [ $stripe_index -eq 0 ] ||
24596                 error "dir0 expect index 0 got $stripe_index"
24597
24598         mkdir $DIR/$tdir/striped_dir/dir1 ||
24599                 error "create dir1 fails"
24600         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24601         [ $stripe_index -eq 1 ] ||
24602                 error "dir1 expect index 1 got $stripe_index"
24603
24604         #check default stripe count/stripe index
24605         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24606         test_300_check_default_striped_dir normal_dir 1 0
24607         test_300_check_default_striped_dir normal_dir -1 1
24608         test_300_check_default_striped_dir normal_dir 2 -1
24609
24610         #delete default stripe information
24611         echo "delete default stripeEA"
24612         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24613                 error "set default stripe on striped dir error"
24614
24615         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24616         for dir in $(find $DIR/$tdir/normal_dir/*); do
24617                 stripe_count=$($LFS getdirstripe -c $dir)
24618                 [ $stripe_count -eq 0 ] ||
24619                         error "expect 1 get $stripe_count for $dir"
24620         done
24621 }
24622 run_test 300g "check default striped directory for normal directory"
24623
24624 test_300h() {
24625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24626         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24627                 skip "Need MDS version at least 2.7.55"
24628
24629         local dir
24630         local stripe_count
24631
24632         mkdir $DIR/$tdir
24633         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24634                 error "set striped dir error"
24635
24636         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24637         test_300_check_default_striped_dir striped_dir 1 0
24638         test_300_check_default_striped_dir striped_dir -1 1
24639         test_300_check_default_striped_dir striped_dir 2 -1
24640
24641         #delete default stripe information
24642         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24643                 error "set default stripe on striped dir error"
24644
24645         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24646         for dir in $(find $DIR/$tdir/striped_dir/*); do
24647                 stripe_count=$($LFS getdirstripe -c $dir)
24648                 [ $stripe_count -eq 0 ] ||
24649                         error "expect 1 get $stripe_count for $dir"
24650         done
24651 }
24652 run_test 300h "check default striped directory for striped directory"
24653
24654 test_300i() {
24655         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24656         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24657         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24658                 skip "Need MDS version at least 2.7.55"
24659
24660         local stripe_count
24661         local file
24662
24663         mkdir $DIR/$tdir
24664
24665         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24666                 error "set striped dir error"
24667
24668         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24669                 error "create files under striped dir failed"
24670
24671         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24672                 error "set striped hashdir error"
24673
24674         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24675                 error "create dir0 under hash dir failed"
24676         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24677                 error "create dir1 under hash dir failed"
24678         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24679                 error "create dir2 under hash dir failed"
24680
24681         # unfortunately, we need to umount to clear dir layout cache for now
24682         # once we fully implement dir layout, we can drop this
24683         umount_client $MOUNT || error "umount failed"
24684         mount_client $MOUNT || error "mount failed"
24685
24686         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24687         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24688         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24689
24690         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24691                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24692                         error "create crush2 dir $tdir/hashdir/d3 failed"
24693                 $LFS find -H crush2 $DIR/$tdir/hashdir
24694                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24695                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24696
24697                 # mkdir with an invalid hash type (hash=fail_val) from client
24698                 # should be replaced on MDS with a valid (default) hash type
24699                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24700                 $LCTL set_param fail_loc=0x1901 fail_val=99
24701                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24702
24703                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24704                 local expect=$(do_facet mds1 \
24705                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24706                 [[ $hash == $expect ]] ||
24707                         error "d99 hash '$hash' != expected hash '$expect'"
24708         fi
24709
24710         #set the stripe to be unknown hash type on read
24711         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24712         $LCTL set_param fail_loc=0x1901 fail_val=99
24713         for ((i = 0; i < 10; i++)); do
24714                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24715                         error "stat f-$i failed"
24716                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24717         done
24718
24719         touch $DIR/$tdir/striped_dir/f0 &&
24720                 error "create under striped dir with unknown hash should fail"
24721
24722         $LCTL set_param fail_loc=0
24723
24724         umount_client $MOUNT || error "umount failed"
24725         mount_client $MOUNT || error "mount failed"
24726
24727         return 0
24728 }
24729 run_test 300i "client handle unknown hash type striped directory"
24730
24731 test_300j() {
24732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24734         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24735                 skip "Need MDS version at least 2.7.55"
24736
24737         local stripe_count
24738         local file
24739
24740         mkdir $DIR/$tdir
24741
24742         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24743         $LCTL set_param fail_loc=0x1702
24744         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24745                 error "set striped dir error"
24746
24747         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24748                 error "create files under striped dir failed"
24749
24750         $LCTL set_param fail_loc=0
24751
24752         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24753
24754         return 0
24755 }
24756 run_test 300j "test large update record"
24757
24758 test_300k() {
24759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24761         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24762                 skip "Need MDS version at least 2.7.55"
24763
24764         # this test needs a huge transaction
24765         local kb
24766         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24767              osd*.$FSNAME-MDT0000.kbytestotal")
24768         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24769
24770         local stripe_count
24771         local file
24772
24773         mkdir $DIR/$tdir
24774
24775         #define OBD_FAIL_LARGE_STRIPE   0x1703
24776         $LCTL set_param fail_loc=0x1703
24777         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24778                 error "set striped dir error"
24779         $LCTL set_param fail_loc=0
24780
24781         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24782                 error "getstripeddir fails"
24783         rm -rf $DIR/$tdir/striped_dir ||
24784                 error "unlink striped dir fails"
24785
24786         return 0
24787 }
24788 run_test 300k "test large striped directory"
24789
24790 test_300l() {
24791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24794                 skip "Need MDS version at least 2.7.55"
24795
24796         local stripe_index
24797
24798         test_mkdir -p $DIR/$tdir/striped_dir
24799         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24800                         error "chown $RUNAS_ID failed"
24801         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24802                 error "set default striped dir failed"
24803
24804         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24805         $LCTL set_param fail_loc=0x80000158
24806         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24807
24808         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24809         [ $stripe_index -eq 1 ] ||
24810                 error "expect 1 get $stripe_index for $dir"
24811 }
24812 run_test 300l "non-root user to create dir under striped dir with stale layout"
24813
24814 test_300m() {
24815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24816         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24818                 skip "Need MDS version at least 2.7.55"
24819
24820         mkdir -p $DIR/$tdir/striped_dir
24821         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24822                 error "set default stripes dir error"
24823
24824         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24825
24826         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24827         [ $stripe_count -eq 0 ] ||
24828                         error "expect 0 get $stripe_count for a"
24829
24830         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24831                 error "set default stripes dir error"
24832
24833         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24834
24835         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24836         [ $stripe_count -eq 0 ] ||
24837                         error "expect 0 get $stripe_count for b"
24838
24839         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24840                 error "set default stripes dir error"
24841
24842         mkdir $DIR/$tdir/striped_dir/c &&
24843                 error "default stripe_index is invalid, mkdir c should fails"
24844
24845         rm -rf $DIR/$tdir || error "rmdir fails"
24846 }
24847 run_test 300m "setstriped directory on single MDT FS"
24848
24849 cleanup_300n() {
24850         local list=$(comma_list $(mdts_nodes))
24851
24852         trap 0
24853         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24854 }
24855
24856 test_300n() {
24857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24859         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24860                 skip "Need MDS version at least 2.7.55"
24861         remote_mds_nodsh && skip "remote MDS with nodsh"
24862
24863         local stripe_index
24864         local list=$(comma_list $(mdts_nodes))
24865
24866         trap cleanup_300n RETURN EXIT
24867         mkdir -p $DIR/$tdir
24868         chmod 777 $DIR/$tdir
24869         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24870                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24871                 error "create striped dir succeeds with gid=0"
24872
24873         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24874         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24875                 error "create striped dir fails with gid=-1"
24876
24877         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24878         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24879                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24880                 error "set default striped dir succeeds with gid=0"
24881
24882
24883         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24884         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24885                 error "set default striped dir fails with gid=-1"
24886
24887
24888         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24889         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24890                                         error "create test_dir fails"
24891         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24892                                         error "create test_dir1 fails"
24893         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24894                                         error "create test_dir2 fails"
24895         cleanup_300n
24896 }
24897 run_test 300n "non-root user to create dir under striped dir with default EA"
24898
24899 test_300o() {
24900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24903                 skip "Need MDS version at least 2.7.55"
24904
24905         local numfree1
24906         local numfree2
24907
24908         mkdir -p $DIR/$tdir
24909
24910         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24911         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24912         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24913                 skip "not enough free inodes $numfree1 $numfree2"
24914         fi
24915
24916         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24917         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24918         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24919                 skip "not enough free space $numfree1 $numfree2"
24920         fi
24921
24922         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24923                 error "setdirstripe fails"
24924
24925         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24926                 error "create dirs fails"
24927
24928         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24929         ls $DIR/$tdir/striped_dir > /dev/null ||
24930                 error "ls striped dir fails"
24931         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24932                 error "unlink big striped dir fails"
24933 }
24934 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24935
24936 test_300p() {
24937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24939         remote_mds_nodsh && skip "remote MDS with nodsh"
24940
24941         mkdir_on_mdt0 $DIR/$tdir
24942
24943         #define OBD_FAIL_OUT_ENOSPC     0x1704
24944         do_facet mds2 lctl set_param fail_loc=0x80001704
24945         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24946                  && error "create striped directory should fail"
24947
24948         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24949
24950         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24951         true
24952 }
24953 run_test 300p "create striped directory without space"
24954
24955 test_300q() {
24956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24958
24959         local fd=$(free_fd)
24960         local cmd="exec $fd<$tdir"
24961         cd $DIR
24962         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24963         eval $cmd
24964         cmd="exec $fd<&-"
24965         trap "eval $cmd" EXIT
24966         cd $tdir || error "cd $tdir fails"
24967         rmdir  ../$tdir || error "rmdir $tdir fails"
24968         mkdir local_dir && error "create dir succeeds"
24969         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24970         eval $cmd
24971         return 0
24972 }
24973 run_test 300q "create remote directory under orphan directory"
24974
24975 test_300r() {
24976         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24977                 skip "Need MDS version at least 2.7.55" && return
24978         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24979
24980         mkdir $DIR/$tdir
24981
24982         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24983                 error "set striped dir error"
24984
24985         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24986                 error "getstripeddir fails"
24987
24988         local stripe_count
24989         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24990                       awk '/lmv_stripe_count:/ { print $2 }')
24991
24992         [ $MDSCOUNT -ne $stripe_count ] &&
24993                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24994
24995         rm -rf $DIR/$tdir/striped_dir ||
24996                 error "unlink striped dir fails"
24997 }
24998 run_test 300r "test -1 striped directory"
24999
25000 test_300s_helper() {
25001         local count=$1
25002
25003         local stripe_dir=$DIR/$tdir/striped_dir.$count
25004
25005         $LFS mkdir -c $count $stripe_dir ||
25006                 error "lfs mkdir -c error"
25007
25008         $LFS getdirstripe $stripe_dir ||
25009                 error "lfs getdirstripe fails"
25010
25011         local stripe_count
25012         stripe_count=$($LFS getdirstripe $stripe_dir |
25013                       awk '/lmv_stripe_count:/ { print $2 }')
25014
25015         [ $count -ne $stripe_count ] &&
25016                 error_noexit "bad stripe count $stripe_count expected $count"
25017
25018         local dupe_stripes
25019         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25020                 awk '/0x/ {count[$1] += 1}; END {
25021                         for (idx in count) {
25022                                 if (count[idx]>1) {
25023                                         print "index " idx " count " count[idx]
25024                                 }
25025                         }
25026                 }')
25027
25028         if [[ -n "$dupe_stripes" ]] ; then
25029                 lfs getdirstripe $stripe_dir
25030                 error_noexit "Dupe MDT above: $dupe_stripes "
25031         fi
25032
25033         rm -rf $stripe_dir ||
25034                 error_noexit "unlink $stripe_dir fails"
25035 }
25036
25037 test_300s() {
25038         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25039                 skip "Need MDS version at least 2.7.55" && return
25040         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25041
25042         mkdir $DIR/$tdir
25043         for count in $(seq 2 $MDSCOUNT); do
25044                 test_300s_helper $count
25045         done
25046 }
25047 run_test 300s "test lfs mkdir -c without -i"
25048
25049 test_300t() {
25050         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25051                 skip "need MDS 2.14.55 or later"
25052         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25053
25054         local testdir="$DIR/$tdir/striped_dir"
25055         local dir1=$testdir/dir1
25056         local dir2=$testdir/dir2
25057
25058         mkdir -p $testdir
25059
25060         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25061                 error "failed to set default stripe count for $testdir"
25062
25063         mkdir $dir1
25064         local stripe_count=$($LFS getdirstripe -c $dir1)
25065
25066         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25067
25068         local max_count=$((MDSCOUNT - 1))
25069         local mdts=$(comma_list $(mdts_nodes))
25070
25071         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25072         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25073
25074         mkdir $dir2
25075         stripe_count=$($LFS getdirstripe -c $dir2)
25076
25077         (( $stripe_count == $max_count )) || error "wrong stripe count"
25078 }
25079 run_test 300t "test max_mdt_stripecount"
25080
25081 prepare_remote_file() {
25082         mkdir $DIR/$tdir/src_dir ||
25083                 error "create remote source failed"
25084
25085         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25086                  error "cp to remote source failed"
25087         touch $DIR/$tdir/src_dir/a
25088
25089         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25090                 error "create remote target dir failed"
25091
25092         touch $DIR/$tdir/tgt_dir/b
25093
25094         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25095                 error "rename dir cross MDT failed!"
25096
25097         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25098                 error "src_child still exists after rename"
25099
25100         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25101                 error "missing file(a) after rename"
25102
25103         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25104                 error "diff after rename"
25105 }
25106
25107 test_310a() {
25108         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25110
25111         local remote_file=$DIR/$tdir/tgt_dir/b
25112
25113         mkdir -p $DIR/$tdir
25114
25115         prepare_remote_file || error "prepare remote file failed"
25116
25117         #open-unlink file
25118         $OPENUNLINK $remote_file $remote_file ||
25119                 error "openunlink $remote_file failed"
25120         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25121 }
25122 run_test 310a "open unlink remote file"
25123
25124 test_310b() {
25125         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25127
25128         local remote_file=$DIR/$tdir/tgt_dir/b
25129
25130         mkdir -p $DIR/$tdir
25131
25132         prepare_remote_file || error "prepare remote file failed"
25133
25134         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25135         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25136         $CHECKSTAT -t file $remote_file || error "check file failed"
25137 }
25138 run_test 310b "unlink remote file with multiple links while open"
25139
25140 test_310c() {
25141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25142         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25143
25144         local remote_file=$DIR/$tdir/tgt_dir/b
25145
25146         mkdir -p $DIR/$tdir
25147
25148         prepare_remote_file || error "prepare remote file failed"
25149
25150         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25151         multiop_bg_pause $remote_file O_uc ||
25152                         error "mulitop failed for remote file"
25153         MULTIPID=$!
25154         $MULTIOP $DIR/$tfile Ouc
25155         kill -USR1 $MULTIPID
25156         wait $MULTIPID
25157 }
25158 run_test 310c "open-unlink remote file with multiple links"
25159
25160 #LU-4825
25161 test_311() {
25162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25163         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25164         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25165                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25166         remote_mds_nodsh && skip "remote MDS with nodsh"
25167
25168         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25169         local mdts=$(comma_list $(mdts_nodes))
25170
25171         mkdir -p $DIR/$tdir
25172         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25173         createmany -o $DIR/$tdir/$tfile. 1000
25174
25175         # statfs data is not real time, let's just calculate it
25176         old_iused=$((old_iused + 1000))
25177
25178         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25179                         osp.*OST0000*MDT0000.create_count")
25180         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25181                                 osp.*OST0000*MDT0000.max_create_count")
25182         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25183
25184         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25185         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25186         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25187
25188         unlinkmany $DIR/$tdir/$tfile. 1000
25189
25190         do_nodes $mdts "$LCTL set_param -n \
25191                         osp.*OST0000*.max_create_count=$max_count"
25192         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25193                 do_nodes $mdts "$LCTL set_param -n \
25194                                 osp.*OST0000*.create_count=$count"
25195         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25196                         grep "=0" && error "create_count is zero"
25197
25198         local new_iused
25199         for i in $(seq 120); do
25200                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25201                 # system may be too busy to destroy all objs in time, use
25202                 # a somewhat small value to not fail autotest
25203                 [ $((old_iused - new_iused)) -gt 400 ] && break
25204                 sleep 1
25205         done
25206
25207         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25208         [ $((old_iused - new_iused)) -gt 400 ] ||
25209                 error "objs not destroyed after unlink"
25210 }
25211 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25212
25213 zfs_get_objid()
25214 {
25215         local ost=$1
25216         local tf=$2
25217         local fid=($($LFS getstripe $tf | grep 0x))
25218         local seq=${fid[3]#0x}
25219         local objid=${fid[1]}
25220
25221         local vdevdir=$(dirname $(facet_vdevice $ost))
25222         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25223         local zfs_zapid=$(do_facet $ost $cmd |
25224                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25225                           awk '/Object/{getline; print $1}')
25226         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25227                           awk "/$objid = /"'{printf $3}')
25228
25229         echo $zfs_objid
25230 }
25231
25232 zfs_object_blksz() {
25233         local ost=$1
25234         local objid=$2
25235
25236         local vdevdir=$(dirname $(facet_vdevice $ost))
25237         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25238         local blksz=$(do_facet $ost $cmd $objid |
25239                       awk '/dblk/{getline; printf $4}')
25240
25241         case "${blksz: -1}" in
25242                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25243                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25244                 *) ;;
25245         esac
25246
25247         echo $blksz
25248 }
25249
25250 test_312() { # LU-4856
25251         remote_ost_nodsh && skip "remote OST with nodsh"
25252         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25253
25254         local max_blksz=$(do_facet ost1 \
25255                           $ZFS get -p recordsize $(facet_device ost1) |
25256                           awk '!/VALUE/{print $3}')
25257         local tf=$DIR/$tfile
25258
25259         $LFS setstripe -c1 $tf
25260         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25261
25262         # Get ZFS object id
25263         local zfs_objid=$(zfs_get_objid $facet $tf)
25264         # block size change by sequential overwrite
25265         local bs
25266
25267         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25268                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25269
25270                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25271                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25272         done
25273         rm -f $tf
25274
25275         $LFS setstripe -c1 $tf
25276         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25277
25278         # block size change by sequential append write
25279         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25280         zfs_objid=$(zfs_get_objid $facet $tf)
25281         local count
25282
25283         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25284                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25285                         oflag=sync conv=notrunc
25286
25287                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25288                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25289                         error "blksz error, actual $blksz, " \
25290                                 "expected: 2 * $count * $PAGE_SIZE"
25291         done
25292         rm -f $tf
25293
25294         # random write
25295         $LFS setstripe -c1 $tf
25296         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25297         zfs_objid=$(zfs_get_objid $facet $tf)
25298
25299         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25300         blksz=$(zfs_object_blksz $facet $zfs_objid)
25301         (( blksz == PAGE_SIZE )) ||
25302                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25303
25304         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25305         blksz=$(zfs_object_blksz $facet $zfs_objid)
25306         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25307
25308         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25309         blksz=$(zfs_object_blksz $facet $zfs_objid)
25310         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25311 }
25312 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25313
25314 test_313() {
25315         remote_ost_nodsh && skip "remote OST with nodsh"
25316
25317         local file=$DIR/$tfile
25318
25319         rm -f $file
25320         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25321
25322         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25323         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25324         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25325                 error "write should failed"
25326         do_facet ost1 "$LCTL set_param fail_loc=0"
25327         rm -f $file
25328 }
25329 run_test 313 "io should fail after last_rcvd update fail"
25330
25331 test_314() {
25332         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25333
25334         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25335         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25336         rm -f $DIR/$tfile
25337         wait_delete_completed
25338         do_facet ost1 "$LCTL set_param fail_loc=0"
25339 }
25340 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25341
25342 test_315() { # LU-618
25343         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25344
25345         local file=$DIR/$tfile
25346         rm -f $file
25347
25348         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25349                 error "multiop file write failed"
25350         $MULTIOP $file oO_RDONLY:r4063232_c &
25351         PID=$!
25352
25353         sleep 2
25354
25355         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25356         kill -USR1 $PID
25357
25358         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25359         rm -f $file
25360 }
25361 run_test 315 "read should be accounted"
25362
25363 test_316() {
25364         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25365         large_xattr_enabled || skip "ea_inode feature disabled"
25366
25367         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25368         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25369         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25370         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25371
25372         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25373 }
25374 run_test 316 "lfs migrate of file with large_xattr enabled"
25375
25376 test_317() {
25377         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25378                 skip "Need MDS version at least 2.11.53"
25379         if [ "$ost1_FSTYPE" == "zfs" ]; then
25380                 skip "LU-10370: no implementation for ZFS"
25381         fi
25382
25383         local trunc_sz
25384         local grant_blk_size
25385
25386         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25387                         awk '/grant_block_size:/ { print $2; exit; }')
25388         #
25389         # Create File of size 5M. Truncate it to below size's and verify
25390         # blocks count.
25391         #
25392         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25393                 error "Create file $DIR/$tfile failed"
25394         stack_trap "rm -f $DIR/$tfile" EXIT
25395
25396         for trunc_sz in 2097152 4097 4000 509 0; do
25397                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25398                         error "truncate $tfile to $trunc_sz failed"
25399                 local sz=$(stat --format=%s $DIR/$tfile)
25400                 local blk=$(stat --format=%b $DIR/$tfile)
25401                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25402                                      grant_blk_size) * 8))
25403
25404                 if [[ $blk -ne $trunc_blk ]]; then
25405                         $(which stat) $DIR/$tfile
25406                         error "Expected Block $trunc_blk got $blk for $tfile"
25407                 fi
25408
25409                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25410                         error "Expected Size $trunc_sz got $sz for $tfile"
25411         done
25412
25413         #
25414         # sparse file test
25415         # Create file with a hole and write actual 65536 bytes which aligned
25416         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25417         #
25418         local bs=65536
25419         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25420                 error "Create file : $DIR/$tfile"
25421
25422         #
25423         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25424         # blocks. The block count must drop to 8.
25425         #
25426         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25427                 ((bs - grant_blk_size) + 1)))
25428         $TRUNCATE $DIR/$tfile $trunc_sz ||
25429                 error "truncate $tfile to $trunc_sz failed"
25430
25431         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25432         sz=$(stat --format=%s $DIR/$tfile)
25433         blk=$(stat --format=%b $DIR/$tfile)
25434
25435         if [[ $blk -ne $trunc_bsz ]]; then
25436                 $(which stat) $DIR/$tfile
25437                 error "Expected Block $trunc_bsz got $blk for $tfile"
25438         fi
25439
25440         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25441                 error "Expected Size $trunc_sz got $sz for $tfile"
25442 }
25443 run_test 317 "Verify blocks get correctly update after truncate"
25444
25445 test_318() {
25446         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25447         local old_max_active=$($LCTL get_param -n \
25448                             ${llite_name}.max_read_ahead_async_active \
25449                             2>/dev/null)
25450
25451         $LCTL set_param llite.*.max_read_ahead_async_active=256
25452         local max_active=$($LCTL get_param -n \
25453                            ${llite_name}.max_read_ahead_async_active \
25454                            2>/dev/null)
25455         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25456
25457         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25458                 error "set max_read_ahead_async_active should succeed"
25459
25460         $LCTL set_param llite.*.max_read_ahead_async_active=512
25461         max_active=$($LCTL get_param -n \
25462                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25463         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25464
25465         # restore @max_active
25466         [ $old_max_active -ne 0 ] && $LCTL set_param \
25467                 llite.*.max_read_ahead_async_active=$old_max_active
25468
25469         local old_threshold=$($LCTL get_param -n \
25470                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25471         local max_per_file_mb=$($LCTL get_param -n \
25472                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25473
25474         local invalid=$(($max_per_file_mb + 1))
25475         $LCTL set_param \
25476                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25477                         && error "set $invalid should fail"
25478
25479         local valid=$(($invalid - 1))
25480         $LCTL set_param \
25481                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25482                         error "set $valid should succeed"
25483         local threshold=$($LCTL get_param -n \
25484                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25485         [ $threshold -eq $valid ] || error \
25486                 "expect threshold $valid got $threshold"
25487         $LCTL set_param \
25488                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25489 }
25490 run_test 318 "Verify async readahead tunables"
25491
25492 test_319() {
25493         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25494
25495         local before=$(date +%s)
25496         local evict
25497         local mdir=$DIR/$tdir
25498         local file=$mdir/xxx
25499
25500         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25501         touch $file
25502
25503 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25504         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25505         $LFS migrate -m1 $mdir &
25506
25507         sleep 1
25508         dd if=$file of=/dev/null
25509         wait
25510         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25511           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25512
25513         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25514 }
25515 run_test 319 "lost lease lock on migrate error"
25516
25517 test_398a() { # LU-4198
25518         local ost1_imp=$(get_osc_import_name client ost1)
25519         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25520                          cut -d'.' -f2)
25521
25522         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25523         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25524
25525         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25526         # request a new lock on client
25527         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25528
25529         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25530         #local lock_count=$($LCTL get_param -n \
25531         #                  ldlm.namespaces.$imp_name.lru_size)
25532         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25533
25534         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25535
25536         # no lock cached, should use lockless DIO and not enqueue new lock
25537         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25538                 conv=notrunc ||
25539                 error "dio write failed"
25540         lock_count=$($LCTL get_param -n \
25541                      ldlm.namespaces.$imp_name.lru_size)
25542         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25543
25544         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25545
25546         # no lock cached, should use locked DIO append
25547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25548                 conv=notrunc || error "DIO append failed"
25549         lock_count=$($LCTL get_param -n \
25550                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25551         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25552 }
25553 run_test 398a "direct IO should cancel lock otherwise lockless"
25554
25555 test_398b() { # LU-4198
25556         local before=$(date +%s)
25557         local njobs=4
25558         local size=48
25559
25560         which fio || skip_env "no fio installed"
25561         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25563
25564         # Single page, multiple pages, stripe size, 4*stripe size
25565         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25566                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25567                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25568                         --numjobs=$njobs --fallocate=none \
25569                         --iodepth=16 --allow_file_create=0 \
25570                         --size=$((size/njobs))M \
25571                         --filename=$DIR/$tfile &
25572                 bg_pid=$!
25573
25574                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25575                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25576                         --numjobs=$njobs --fallocate=none \
25577                         --iodepth=16 --allow_file_create=0 \
25578                         --size=$((size/njobs))M \
25579                         --filename=$DIR/$tfile || true
25580                 wait $bg_pid
25581         done
25582
25583         evict=$(do_facet client $LCTL get_param \
25584                 osc.$FSNAME-OST*-osc-*/state |
25585             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25586
25587         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25588                 (do_facet client $LCTL get_param \
25589                         osc.$FSNAME-OST*-osc-*/state;
25590                     error "eviction happened: $evict before:$before")
25591
25592         rm -f $DIR/$tfile
25593 }
25594 run_test 398b "DIO and buffer IO race"
25595
25596 test_398c() { # LU-4198
25597         local ost1_imp=$(get_osc_import_name client ost1)
25598         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25599                          cut -d'.' -f2)
25600
25601         which fio || skip_env "no fio installed"
25602
25603         saved_debug=$($LCTL get_param -n debug)
25604         $LCTL set_param debug=0
25605
25606         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25607         ((size /= 1024)) # by megabytes
25608         ((size /= 2)) # write half of the OST at most
25609         [ $size -gt 40 ] && size=40 #reduce test time anyway
25610
25611         $LFS setstripe -c 1 $DIR/$tfile
25612
25613         # it seems like ldiskfs reserves more space than necessary if the
25614         # writing blocks are not mapped, so it extends the file firstly
25615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25616         cancel_lru_locks osc
25617
25618         # clear and verify rpc_stats later
25619         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25620
25621         local njobs=4
25622         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25623         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25624                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25625                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25626                 --filename=$DIR/$tfile
25627         [ $? -eq 0 ] || error "fio write error"
25628
25629         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25630                 error "Locks were requested while doing AIO"
25631
25632         # get the percentage of 1-page I/O
25633         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25634                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25635                 awk '{print $7}')
25636         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25637
25638         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25639         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25640                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25641                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25642                 --filename=$DIR/$tfile
25643         [ $? -eq 0 ] || error "fio mixed read write error"
25644
25645         echo "AIO with large block size ${size}M"
25646         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25647                 --numjobs=1 --fallocate=none --ioengine=libaio \
25648                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25649                 --filename=$DIR/$tfile
25650         [ $? -eq 0 ] || error "fio large block size failed"
25651
25652         rm -f $DIR/$tfile
25653         $LCTL set_param debug="$saved_debug"
25654 }
25655 run_test 398c "run fio to test AIO"
25656
25657 test_398d() { #  LU-13846
25658         which aiocp || skip_env "no aiocp installed"
25659         local aio_file=$DIR/$tfile.aio
25660
25661         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25662
25663         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25664         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25665         stack_trap "rm -f $DIR/$tfile $aio_file"
25666
25667         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25668
25669         # make sure we don't crash and fail properly
25670         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25671                 error "aio not aligned with PAGE SIZE should fail"
25672
25673         rm -f $DIR/$tfile $aio_file
25674 }
25675 run_test 398d "run aiocp to verify block size > stripe size"
25676
25677 test_398e() {
25678         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25679         touch $DIR/$tfile.new
25680         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25681 }
25682 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25683
25684 test_398f() { #  LU-14687
25685         which aiocp || skip_env "no aiocp installed"
25686         local aio_file=$DIR/$tfile.aio
25687
25688         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25689
25690         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25691         stack_trap "rm -f $DIR/$tfile $aio_file"
25692
25693         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25694         $LCTL set_param fail_loc=0x1418
25695         # make sure we don't crash and fail properly
25696         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25697                 error "aio with page allocation failure succeeded"
25698         $LCTL set_param fail_loc=0
25699         diff $DIR/$tfile $aio_file
25700         [[ $? != 0 ]] || error "no diff after failed aiocp"
25701 }
25702 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25703
25704 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25705 # stripe and i/o size must be > stripe size
25706 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25707 # single RPC in flight.  This test shows async DIO submission is working by
25708 # showing multiple RPCs in flight.
25709 test_398g() { #  LU-13798
25710         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25711
25712         # We need to do some i/o first to acquire enough grant to put our RPCs
25713         # in flight; otherwise a new connection may not have enough grant
25714         # available
25715         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25716                 error "parallel dio failed"
25717         stack_trap "rm -f $DIR/$tfile"
25718
25719         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25720         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25721         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25722         stack_trap "$LCTL set_param -n $pages_per_rpc"
25723
25724         # Recreate file so it's empty
25725         rm -f $DIR/$tfile
25726         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25727         #Pause rpc completion to guarantee we see multiple rpcs in flight
25728         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25729         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25730         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25731
25732         # Clear rpc stats
25733         $LCTL set_param osc.*.rpc_stats=c
25734
25735         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25736                 error "parallel dio failed"
25737         stack_trap "rm -f $DIR/$tfile"
25738
25739         $LCTL get_param osc.*-OST0000-*.rpc_stats
25740         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25741                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25742                 grep "8:" | awk '{print $8}')
25743         # We look at the "8 rpcs in flight" field, and verify A) it is present
25744         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25745         # as expected for an 8M DIO to a file with 1M stripes.
25746         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25747
25748         # Verify turning off parallel dio works as expected
25749         # Clear rpc stats
25750         $LCTL set_param osc.*.rpc_stats=c
25751         $LCTL set_param llite.*.parallel_dio=0
25752         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25753
25754         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25755                 error "dio with parallel dio disabled failed"
25756
25757         # Ideally, we would see only one RPC in flight here, but there is an
25758         # unavoidable race between i/o completion and RPC in flight counting,
25759         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25760         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25761         # So instead we just verify it's always < 8.
25762         $LCTL get_param osc.*-OST0000-*.rpc_stats
25763         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25764                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25765                 grep '^$' -B1 | grep . | awk '{print $1}')
25766         [ $ret != "8:" ] ||
25767                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25768 }
25769 run_test 398g "verify parallel dio async RPC submission"
25770
25771 test_398h() { #  LU-13798
25772         local dio_file=$DIR/$tfile.dio
25773
25774         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25775
25776         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25777         stack_trap "rm -f $DIR/$tfile $dio_file"
25778
25779         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25780                 error "parallel dio failed"
25781         diff $DIR/$tfile $dio_file
25782         [[ $? == 0 ]] || error "file diff after aiocp"
25783 }
25784 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25785
25786 test_398i() { #  LU-13798
25787         local dio_file=$DIR/$tfile.dio
25788
25789         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25790
25791         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25792         stack_trap "rm -f $DIR/$tfile $dio_file"
25793
25794         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25795         $LCTL set_param fail_loc=0x1418
25796         # make sure we don't crash and fail properly
25797         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25798                 error "parallel dio page allocation failure succeeded"
25799         diff $DIR/$tfile $dio_file
25800         [[ $? != 0 ]] || error "no diff after failed aiocp"
25801 }
25802 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25803
25804 test_398j() { #  LU-13798
25805         # Stripe size > RPC size but less than i/o size tests split across
25806         # stripes and RPCs for individual i/o op
25807         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25808
25809         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25810         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25811         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25812         stack_trap "$LCTL set_param -n $pages_per_rpc"
25813
25814         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25815                 error "parallel dio write failed"
25816         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25817
25818         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25819                 error "parallel dio read failed"
25820         diff $DIR/$tfile $DIR/$tfile.2
25821         [[ $? == 0 ]] || error "file diff after parallel dio read"
25822 }
25823 run_test 398j "test parallel dio where stripe size > rpc_size"
25824
25825 test_398k() { #  LU-13798
25826         wait_delete_completed
25827         wait_mds_ost_sync
25828
25829         # 4 stripe file; we will cause out of space on OST0
25830         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25831
25832         # Fill OST0 (if it's not too large)
25833         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25834                    head -n1)
25835         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25836                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25837         fi
25838         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25839         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25840                 error "dd should fill OST0"
25841         stack_trap "rm -f $DIR/$tfile.1"
25842
25843         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25844         err=$?
25845
25846         ls -la $DIR/$tfile
25847         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25848                 error "file is not 0 bytes in size"
25849
25850         # dd above should not succeed, but don't error until here so we can
25851         # get debug info above
25852         [[ $err != 0 ]] ||
25853                 error "parallel dio write with enospc succeeded"
25854         stack_trap "rm -f $DIR/$tfile"
25855 }
25856 run_test 398k "test enospc on first stripe"
25857
25858 test_398l() { #  LU-13798
25859         wait_delete_completed
25860         wait_mds_ost_sync
25861
25862         # 4 stripe file; we will cause out of space on OST0
25863         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25864         # happens on the second i/o chunk we issue
25865         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25866
25867         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25868         stack_trap "rm -f $DIR/$tfile"
25869
25870         # Fill OST0 (if it's not too large)
25871         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25872                    head -n1)
25873         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25874                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25875         fi
25876         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25877         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25878                 error "dd should fill OST0"
25879         stack_trap "rm -f $DIR/$tfile.1"
25880
25881         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25882         err=$?
25883         stack_trap "rm -f $DIR/$tfile.2"
25884
25885         # Check that short write completed as expected
25886         ls -la $DIR/$tfile.2
25887         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25888                 error "file is not 1M in size"
25889
25890         # dd above should not succeed, but don't error until here so we can
25891         # get debug info above
25892         [[ $err != 0 ]] ||
25893                 error "parallel dio write with enospc succeeded"
25894
25895         # Truncate source file to same length as output file and diff them
25896         $TRUNCATE $DIR/$tfile 1048576
25897         diff $DIR/$tfile $DIR/$tfile.2
25898         [[ $? == 0 ]] || error "data incorrect after short write"
25899 }
25900 run_test 398l "test enospc on intermediate stripe/RPC"
25901
25902 test_398m() { #  LU-13798
25903         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25904
25905         # Set up failure on OST0, the first stripe:
25906         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25907         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25908         # OST0 is on ost1, OST1 is on ost2.
25909         # So this fail_val specifies OST0
25910         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25911         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25912
25913         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25914                 error "parallel dio write with failure on first stripe succeeded"
25915         stack_trap "rm -f $DIR/$tfile"
25916         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25917
25918         # Place data in file for read
25919         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25920                 error "parallel dio write failed"
25921
25922         # Fail read on OST0, first stripe
25923         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25924         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25925         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25926                 error "parallel dio read with error on first stripe succeeded"
25927         rm -f $DIR/$tfile.2
25928         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25929
25930         # Switch to testing on OST1, second stripe
25931         # Clear file contents, maintain striping
25932         echo > $DIR/$tfile
25933         # Set up failure on OST1, second stripe:
25934         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25935         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25936
25937         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25938                 error "parallel dio write with failure on second stripe succeeded"
25939         stack_trap "rm -f $DIR/$tfile"
25940         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25941
25942         # Place data in file for read
25943         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25944                 error "parallel dio write failed"
25945
25946         # Fail read on OST1, second stripe
25947         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25948         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25949         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25950                 error "parallel dio read with error on second stripe succeeded"
25951         rm -f $DIR/$tfile.2
25952         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25953 }
25954 run_test 398m "test RPC failures with parallel dio"
25955
25956 # Parallel submission of DIO should not cause problems for append, but it's
25957 # important to verify.
25958 test_398n() { #  LU-13798
25959         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25960
25961         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25962                 error "dd to create source file failed"
25963         stack_trap "rm -f $DIR/$tfile"
25964
25965         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25966                 error "parallel dio write with failure on second stripe succeeded"
25967         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25968         diff $DIR/$tfile $DIR/$tfile.1
25969         [[ $? == 0 ]] || error "data incorrect after append"
25970
25971 }
25972 run_test 398n "test append with parallel DIO"
25973
25974 test_398o() {
25975         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25976 }
25977 run_test 398o "right kms with DIO"
25978
25979 test_fake_rw() {
25980         local read_write=$1
25981         if [ "$read_write" = "write" ]; then
25982                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25983         elif [ "$read_write" = "read" ]; then
25984                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25985         else
25986                 error "argument error"
25987         fi
25988
25989         # turn off debug for performance testing
25990         local saved_debug=$($LCTL get_param -n debug)
25991         $LCTL set_param debug=0
25992
25993         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25994
25995         # get ost1 size - $FSNAME-OST0000
25996         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25997         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25998         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25999
26000         if [ "$read_write" = "read" ]; then
26001                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26002         fi
26003
26004         local start_time=$(date +%s.%N)
26005         $dd_cmd bs=1M count=$blocks oflag=sync ||
26006                 error "real dd $read_write error"
26007         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26008
26009         if [ "$read_write" = "write" ]; then
26010                 rm -f $DIR/$tfile
26011         fi
26012
26013         # define OBD_FAIL_OST_FAKE_RW           0x238
26014         do_facet ost1 $LCTL set_param fail_loc=0x238
26015
26016         local start_time=$(date +%s.%N)
26017         $dd_cmd bs=1M count=$blocks oflag=sync ||
26018                 error "fake dd $read_write error"
26019         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26020
26021         if [ "$read_write" = "write" ]; then
26022                 # verify file size
26023                 cancel_lru_locks osc
26024                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26025                         error "$tfile size not $blocks MB"
26026         fi
26027         do_facet ost1 $LCTL set_param fail_loc=0
26028
26029         echo "fake $read_write $duration_fake vs. normal $read_write" \
26030                 "$duration in seconds"
26031         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26032                 error_not_in_vm "fake write is slower"
26033
26034         $LCTL set_param -n debug="$saved_debug"
26035         rm -f $DIR/$tfile
26036 }
26037 test_399a() { # LU-7655 for OST fake write
26038         remote_ost_nodsh && skip "remote OST with nodsh"
26039
26040         test_fake_rw write
26041 }
26042 run_test 399a "fake write should not be slower than normal write"
26043
26044 test_399b() { # LU-8726 for OST fake read
26045         remote_ost_nodsh && skip "remote OST with nodsh"
26046         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26047                 skip_env "ldiskfs only test"
26048         fi
26049
26050         test_fake_rw read
26051 }
26052 run_test 399b "fake read should not be slower than normal read"
26053
26054 test_400a() { # LU-1606, was conf-sanity test_74
26055         if ! which $CC > /dev/null 2>&1; then
26056                 skip_env "$CC is not installed"
26057         fi
26058
26059         local extra_flags=''
26060         local out=$TMP/$tfile
26061         local prefix=/usr/include/lustre
26062         local prog
26063
26064         # Oleg removes .c files in his test rig so test if any c files exist
26065         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26066                 skip_env "Needed .c test files are missing"
26067
26068         if ! [[ -d $prefix ]]; then
26069                 # Assume we're running in tree and fixup the include path.
26070                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26071                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26072                 extra_flags+=" -L$LUSTRE/utils/.libs"
26073         fi
26074
26075         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26076                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26077                         error "client api broken"
26078         done
26079         rm -f $out
26080 }
26081 run_test 400a "Lustre client api program can compile and link"
26082
26083 test_400b() { # LU-1606, LU-5011
26084         local header
26085         local out=$TMP/$tfile
26086         local prefix=/usr/include/linux/lustre
26087
26088         # We use a hard coded prefix so that this test will not fail
26089         # when run in tree. There are headers in lustre/include/lustre/
26090         # that are not packaged (like lustre_idl.h) and have more
26091         # complicated include dependencies (like config.h and lnet/types.h).
26092         # Since this test about correct packaging we just skip them when
26093         # they don't exist (see below) rather than try to fixup cppflags.
26094
26095         if ! which $CC > /dev/null 2>&1; then
26096                 skip_env "$CC is not installed"
26097         fi
26098
26099         for header in $prefix/*.h; do
26100                 if ! [[ -f "$header" ]]; then
26101                         continue
26102                 fi
26103
26104                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26105                         continue # lustre_ioctl.h is internal header
26106                 fi
26107
26108                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26109                         error "cannot compile '$header'"
26110         done
26111         rm -f $out
26112 }
26113 run_test 400b "packaged headers can be compiled"
26114
26115 test_401a() { #LU-7437
26116         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26117         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26118
26119         #count the number of parameters by "list_param -R"
26120         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26121         #count the number of parameters by listing proc files
26122         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26123         echo "proc_dirs='$proc_dirs'"
26124         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26125         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26126                       sort -u | wc -l)
26127
26128         [ $params -eq $procs ] ||
26129                 error "found $params parameters vs. $procs proc files"
26130
26131         # test the list_param -D option only returns directories
26132         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26133         #count the number of parameters by listing proc directories
26134         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26135                 sort -u | wc -l)
26136
26137         [ $params -eq $procs ] ||
26138                 error "found $params parameters vs. $procs proc files"
26139 }
26140 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26141
26142 test_401b() {
26143         # jobid_var may not allow arbitrary values, so use jobid_name
26144         # if available
26145         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26146                 local testname=jobid_name tmp='testing%p'
26147         else
26148                 local testname=jobid_var tmp=testing
26149         fi
26150
26151         local save=$($LCTL get_param -n $testname)
26152
26153         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26154                 error "no error returned when setting bad parameters"
26155
26156         local jobid_new=$($LCTL get_param -n foe $testname baz)
26157         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26158
26159         $LCTL set_param -n fog=bam $testname=$save bat=fog
26160         local jobid_old=$($LCTL get_param -n foe $testname bag)
26161         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26162 }
26163 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26164
26165 test_401c() {
26166         # jobid_var may not allow arbitrary values, so use jobid_name
26167         # if available
26168         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26169                 local testname=jobid_name
26170         else
26171                 local testname=jobid_var
26172         fi
26173
26174         local jobid_var_old=$($LCTL get_param -n $testname)
26175         local jobid_var_new
26176
26177         $LCTL set_param $testname= &&
26178                 error "no error returned for 'set_param a='"
26179
26180         jobid_var_new=$($LCTL get_param -n $testname)
26181         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26182                 error "$testname was changed by setting without value"
26183
26184         $LCTL set_param $testname &&
26185                 error "no error returned for 'set_param a'"
26186
26187         jobid_var_new=$($LCTL get_param -n $testname)
26188         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26189                 error "$testname was changed by setting without value"
26190 }
26191 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26192
26193 test_401d() {
26194         # jobid_var may not allow arbitrary values, so use jobid_name
26195         # if available
26196         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26197                 local testname=jobid_name new_value='foo=bar%p'
26198         else
26199                 local testname=jobid_var new_valuie=foo=bar
26200         fi
26201
26202         local jobid_var_old=$($LCTL get_param -n $testname)
26203         local jobid_var_new
26204
26205         $LCTL set_param $testname=$new_value ||
26206                 error "'set_param a=b' did not accept a value containing '='"
26207
26208         jobid_var_new=$($LCTL get_param -n $testname)
26209         [[ "$jobid_var_new" == "$new_value" ]] ||
26210                 error "'set_param a=b' failed on a value containing '='"
26211
26212         # Reset the $testname to test the other format
26213         $LCTL set_param $testname=$jobid_var_old
26214         jobid_var_new=$($LCTL get_param -n $testname)
26215         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26216                 error "failed to reset $testname"
26217
26218         $LCTL set_param $testname $new_value ||
26219                 error "'set_param a b' did not accept a value containing '='"
26220
26221         jobid_var_new=$($LCTL get_param -n $testname)
26222         [[ "$jobid_var_new" == "$new_value" ]] ||
26223                 error "'set_param a b' failed on a value containing '='"
26224
26225         $LCTL set_param $testname $jobid_var_old
26226         jobid_var_new=$($LCTL get_param -n $testname)
26227         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26228                 error "failed to reset $testname"
26229 }
26230 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26231
26232 test_401e() { # LU-14779
26233         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26234                 error "lctl list_param MGC* failed"
26235         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26236         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26237                 error "lctl get_param lru_size failed"
26238 }
26239 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26240
26241 test_402() {
26242         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26243         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26244                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26245         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26246                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26247                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26248         remote_mds_nodsh && skip "remote MDS with nodsh"
26249
26250         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26251 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26252         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26253         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26254                 echo "Touch failed - OK"
26255 }
26256 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26257
26258 test_403() {
26259         local file1=$DIR/$tfile.1
26260         local file2=$DIR/$tfile.2
26261         local tfile=$TMP/$tfile
26262
26263         rm -f $file1 $file2 $tfile
26264
26265         touch $file1
26266         ln $file1 $file2
26267
26268         # 30 sec OBD_TIMEOUT in ll_getattr()
26269         # right before populating st_nlink
26270         $LCTL set_param fail_loc=0x80001409
26271         stat -c %h $file1 > $tfile &
26272
26273         # create an alias, drop all locks and reclaim the dentry
26274         < $file2
26275         cancel_lru_locks mdc
26276         cancel_lru_locks osc
26277         sysctl -w vm.drop_caches=2
26278
26279         wait
26280
26281         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26282
26283         rm -f $tfile $file1 $file2
26284 }
26285 run_test 403 "i_nlink should not drop to zero due to aliasing"
26286
26287 test_404() { # LU-6601
26288         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26289                 skip "Need server version newer than 2.8.52"
26290         remote_mds_nodsh && skip "remote MDS with nodsh"
26291
26292         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26293                 awk '/osp .*-osc-MDT/ { print $4}')
26294
26295         local osp
26296         for osp in $mosps; do
26297                 echo "Deactivate: " $osp
26298                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26299                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26300                         awk -vp=$osp '$4 == p { print $2 }')
26301                 [ $stat = IN ] || {
26302                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26303                         error "deactivate error"
26304                 }
26305                 echo "Activate: " $osp
26306                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26307                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26308                         awk -vp=$osp '$4 == p { print $2 }')
26309                 [ $stat = UP ] || {
26310                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26311                         error "activate error"
26312                 }
26313         done
26314 }
26315 run_test 404 "validate manual {de}activated works properly for OSPs"
26316
26317 test_405() {
26318         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26319         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26320                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26321                         skip "Layout swap lock is not supported"
26322
26323         check_swap_layouts_support
26324         check_swap_layout_no_dom $DIR
26325
26326         test_mkdir $DIR/$tdir
26327         swap_lock_test -d $DIR/$tdir ||
26328                 error "One layout swap locked test failed"
26329 }
26330 run_test 405 "Various layout swap lock tests"
26331
26332 test_406() {
26333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26334         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26335         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26337         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26338                 skip "Need MDS version at least 2.8.50"
26339
26340         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26341         local test_pool=$TESTNAME
26342
26343         pool_add $test_pool || error "pool_add failed"
26344         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26345                 error "pool_add_targets failed"
26346
26347         save_layout_restore_at_exit $MOUNT
26348
26349         # parent set default stripe count only, child will stripe from both
26350         # parent and fs default
26351         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26352                 error "setstripe $MOUNT failed"
26353         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26354         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26355         for i in $(seq 10); do
26356                 local f=$DIR/$tdir/$tfile.$i
26357                 touch $f || error "touch failed"
26358                 local count=$($LFS getstripe -c $f)
26359                 [ $count -eq $OSTCOUNT ] ||
26360                         error "$f stripe count $count != $OSTCOUNT"
26361                 local offset=$($LFS getstripe -i $f)
26362                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26363                 local size=$($LFS getstripe -S $f)
26364                 [ $size -eq $((def_stripe_size * 2)) ] ||
26365                         error "$f stripe size $size != $((def_stripe_size * 2))"
26366                 local pool=$($LFS getstripe -p $f)
26367                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26368         done
26369
26370         # change fs default striping, delete parent default striping, now child
26371         # will stripe from new fs default striping only
26372         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26373                 error "change $MOUNT default stripe failed"
26374         $LFS setstripe -c 0 $DIR/$tdir ||
26375                 error "delete $tdir default stripe failed"
26376         for i in $(seq 11 20); do
26377                 local f=$DIR/$tdir/$tfile.$i
26378                 touch $f || error "touch $f failed"
26379                 local count=$($LFS getstripe -c $f)
26380                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26381                 local offset=$($LFS getstripe -i $f)
26382                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26383                 local size=$($LFS getstripe -S $f)
26384                 [ $size -eq $def_stripe_size ] ||
26385                         error "$f stripe size $size != $def_stripe_size"
26386                 local pool=$($LFS getstripe -p $f)
26387                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26388         done
26389
26390         unlinkmany $DIR/$tdir/$tfile. 1 20
26391
26392         local f=$DIR/$tdir/$tfile
26393         pool_remove_all_targets $test_pool $f
26394         pool_remove $test_pool $f
26395 }
26396 run_test 406 "DNE support fs default striping"
26397
26398 test_407() {
26399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26400         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26401                 skip "Need MDS version at least 2.8.55"
26402         remote_mds_nodsh && skip "remote MDS with nodsh"
26403
26404         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26405                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26406         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26407                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26408         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26409
26410         #define OBD_FAIL_DT_TXN_STOP    0x2019
26411         for idx in $(seq $MDSCOUNT); do
26412                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26413         done
26414         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26415         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26416                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26417         true
26418 }
26419 run_test 407 "transaction fail should cause operation fail"
26420
26421 test_408() {
26422         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26423
26424         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26425         lctl set_param fail_loc=0x8000040a
26426         # let ll_prepare_partial_page() fail
26427         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26428
26429         rm -f $DIR/$tfile
26430
26431         # create at least 100 unused inodes so that
26432         # shrink_icache_memory(0) should not return 0
26433         touch $DIR/$tfile-{0..100}
26434         rm -f $DIR/$tfile-{0..100}
26435         sync
26436
26437         echo 2 > /proc/sys/vm/drop_caches
26438 }
26439 run_test 408 "drop_caches should not hang due to page leaks"
26440
26441 test_409()
26442 {
26443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26444
26445         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26446         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26447         touch $DIR/$tdir/guard || error "(2) Fail to create"
26448
26449         local PREFIX=$(str_repeat 'A' 128)
26450         echo "Create 1K hard links start at $(date)"
26451         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26452                 error "(3) Fail to hard link"
26453
26454         echo "Links count should be right although linkEA overflow"
26455         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26456         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26457         [ $linkcount -eq 1001 ] ||
26458                 error "(5) Unexpected hard links count: $linkcount"
26459
26460         echo "List all links start at $(date)"
26461         ls -l $DIR/$tdir/foo > /dev/null ||
26462                 error "(6) Fail to list $DIR/$tdir/foo"
26463
26464         echo "Unlink hard links start at $(date)"
26465         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26466                 error "(7) Fail to unlink"
26467         echo "Unlink hard links finished at $(date)"
26468 }
26469 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26470
26471 test_410()
26472 {
26473         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26474                 skip "Need client version at least 2.9.59"
26475         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26476                 skip "Need MODULES build"
26477
26478         # Create a file, and stat it from the kernel
26479         local testfile=$DIR/$tfile
26480         touch $testfile
26481
26482         local run_id=$RANDOM
26483         local my_ino=$(stat --format "%i" $testfile)
26484
26485         # Try to insert the module. This will always fail as the
26486         # module is designed to not be inserted.
26487         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26488             &> /dev/null
26489
26490         # Anything but success is a test failure
26491         dmesg | grep -q \
26492             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26493             error "no inode match"
26494 }
26495 run_test 410 "Test inode number returned from kernel thread"
26496
26497 cleanup_test411_cgroup() {
26498         trap 0
26499         rmdir "$1"
26500 }
26501
26502 test_411() {
26503         local cg_basedir=/sys/fs/cgroup/memory
26504         # LU-9966
26505         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26506                 skip "no setup for cgroup"
26507
26508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26509                 error "test file creation failed"
26510         cancel_lru_locks osc
26511
26512         # Create a very small memory cgroup to force a slab allocation error
26513         local cgdir=$cg_basedir/osc_slab_alloc
26514         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26515         trap "cleanup_test411_cgroup $cgdir" EXIT
26516         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26517         echo 1M > $cgdir/memory.limit_in_bytes
26518
26519         # Should not LBUG, just be killed by oom-killer
26520         # dd will return 0 even allocation failure in some environment.
26521         # So don't check return value
26522         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26523         cleanup_test411_cgroup $cgdir
26524
26525         return 0
26526 }
26527 run_test 411 "Slab allocation error with cgroup does not LBUG"
26528
26529 test_412() {
26530         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26531         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26532                 skip "Need server version at least 2.10.55"
26533
26534         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26535                 error "mkdir failed"
26536         $LFS getdirstripe $DIR/$tdir
26537         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26538         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26539                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26540         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26541         [ $stripe_count -eq 2 ] ||
26542                 error "expect 2 get $stripe_count"
26543
26544         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26545
26546         local index
26547         local index2
26548
26549         # subdirs should be on the same MDT as parent
26550         for i in $(seq 0 $((MDSCOUNT - 1))); do
26551                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26552                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26553                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26554                 (( index == i )) || error "mdt$i/sub on MDT$index"
26555         done
26556
26557         # stripe offset -1, ditto
26558         for i in {1..10}; do
26559                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26560                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26561                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26562                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26563                 (( index == index2 )) ||
26564                         error "qos$i on MDT$index, sub on MDT$index2"
26565         done
26566
26567         local testdir=$DIR/$tdir/inherit
26568
26569         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26570         # inherit 2 levels
26571         for i in 1 2; do
26572                 testdir=$testdir/s$i
26573                 mkdir $testdir || error "mkdir $testdir failed"
26574                 index=$($LFS getstripe -m $testdir)
26575                 (( index == 1 )) ||
26576                         error "$testdir on MDT$index"
26577         done
26578
26579         # not inherit any more
26580         testdir=$testdir/s3
26581         mkdir $testdir || error "mkdir $testdir failed"
26582         getfattr -d -m dmv $testdir | grep dmv &&
26583                 error "default LMV set on $testdir" || true
26584 }
26585 run_test 412 "mkdir on specific MDTs"
26586
26587 TEST413_COUNT=${TEST413_COUNT:-200}
26588
26589 #
26590 # set_maxage() is used by test_413 only.
26591 # This is a helper function to set maxage. Does not return any value.
26592 # Input: maxage to set
26593 #
26594 set_maxage() {
26595         local lmv_qos_maxage
26596         local lod_qos_maxage
26597         local new_maxage=$1
26598
26599         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26600         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26601         stack_trap "$LCTL set_param \
26602                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26603         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26604                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26605         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26606                 lod.*.mdt_qos_maxage=$new_maxage
26607         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26608                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26609 }
26610
26611 generate_uneven_mdts() {
26612         local threshold=$1
26613         local ffree
26614         local bavail
26615         local max
26616         local min
26617         local max_index
26618         local min_index
26619         local tmp
26620         local i
26621
26622         echo
26623         echo "Check for uneven MDTs: "
26624
26625         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26626         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26627         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26628
26629         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26630         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26631         max_index=0
26632         min_index=0
26633         for ((i = 1; i < ${#ffree[@]}; i++)); do
26634                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26635                 if [ $tmp -gt $max ]; then
26636                         max=$tmp
26637                         max_index=$i
26638                 fi
26639                 if [ $tmp -lt $min ]; then
26640                         min=$tmp
26641                         min_index=$i
26642                 fi
26643         done
26644
26645         (( min > 0 )) || skip "low space on MDT$min_index"
26646         (( ${ffree[min_index]} > 0 )) ||
26647                 skip "no free files on MDT$min_index"
26648         (( ${ffree[min_index]} < 10000000 )) ||
26649                 skip "too many free files on MDT$min_index"
26650
26651         # Check if we need to generate uneven MDTs
26652         local diff=$(((max - min) * 100 / min))
26653         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26654         local testdir # individual folder within $testdirp
26655         local start
26656         local cmd
26657
26658         # fallocate is faster to consume space on MDT, if available
26659         if check_fallocate_supported mds$((min_index + 1)); then
26660                 cmd="fallocate -l 128K "
26661         else
26662                 cmd="dd if=/dev/zero bs=128K count=1 of="
26663         fi
26664
26665         echo "using cmd $cmd"
26666         for (( i = 0; diff < threshold; i++ )); do
26667                 testdir=${testdirp}/$i
26668                 [ -d $testdir ] && continue
26669
26670                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26671
26672                 mkdir -p $testdirp
26673                 # generate uneven MDTs, create till $threshold% diff
26674                 echo -n "weight diff=$diff% must be > $threshold% ..."
26675                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26676                 $LFS mkdir -i $min_index $testdir ||
26677                         error "mkdir $testdir failed"
26678                 $LFS setstripe -E 1M -L mdt $testdir ||
26679                         error "setstripe $testdir failed"
26680                 start=$SECONDS
26681                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26682                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26683                 done
26684                 sync; sleep 1; sync
26685
26686                 # wait for QOS to update
26687                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26688
26689                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26690                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26691                 max=$(((${ffree[max_index]} >> 8) *
26692                         (${bavail[max_index]} * bsize >> 16)))
26693                 min=$(((${ffree[min_index]} >> 8) *
26694                         (${bavail[min_index]} * bsize >> 16)))
26695                 (( min > 0 )) || skip "low space on MDT$min_index"
26696                 diff=$(((max - min) * 100 / min))
26697         done
26698
26699         echo "MDT filesfree available: ${ffree[*]}"
26700         echo "MDT blocks available: ${bavail[*]}"
26701         echo "weight diff=$diff%"
26702 }
26703
26704 test_qos_mkdir() {
26705         local mkdir_cmd=$1
26706         local stripe_count=$2
26707         local mdts=$(comma_list $(mdts_nodes))
26708
26709         local testdir
26710         local lmv_qos_prio_free
26711         local lmv_qos_threshold_rr
26712         local lod_qos_prio_free
26713         local lod_qos_threshold_rr
26714         local total
26715         local count
26716         local i
26717
26718         # @total is total directories created if it's testing plain
26719         # directories, otherwise it's total stripe object count for
26720         # striped directories test.
26721         # remote/striped directory unlinking is slow on zfs and may
26722         # timeout, test with fewer directories
26723         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26724
26725         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26726         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26727         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26728                 head -n1)
26729         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26730         stack_trap "$LCTL set_param \
26731                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26732         stack_trap "$LCTL set_param \
26733                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26734
26735         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26736                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26737         lod_qos_prio_free=${lod_qos_prio_free%%%}
26738         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26739                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26740         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26741         stack_trap "do_nodes $mdts $LCTL set_param \
26742                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26743         stack_trap "do_nodes $mdts $LCTL set_param \
26744                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26745
26746         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26747         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26748
26749         testdir=$DIR/$tdir-s$stripe_count/rr
26750
26751         local stripe_index=$($LFS getstripe -m $testdir)
26752         local test_mkdir_rr=true
26753
26754         getfattr -d -m dmv -e hex $testdir | grep dmv
26755         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26756                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26757                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26758                         test_mkdir_rr=false
26759         fi
26760
26761         echo
26762         $test_mkdir_rr &&
26763                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26764                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26765
26766         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26767         for (( i = 0; i < total / stripe_count; i++ )); do
26768                 eval $mkdir_cmd $testdir/subdir$i ||
26769                         error "$mkdir_cmd subdir$i failed"
26770         done
26771
26772         for (( i = 0; i < $MDSCOUNT; i++ )); do
26773                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26774                 echo "$count directories created on MDT$i"
26775                 if $test_mkdir_rr; then
26776                         (( count == total / stripe_count / MDSCOUNT )) ||
26777                                 error "subdirs are not evenly distributed"
26778                 elif (( i == stripe_index )); then
26779                         (( count == total / stripe_count )) ||
26780                                 error "$count subdirs created on MDT$i"
26781                 else
26782                         (( count == 0 )) ||
26783                                 error "$count subdirs created on MDT$i"
26784                 fi
26785
26786                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26787                         count=$($LFS getdirstripe $testdir/* |
26788                                 grep -c -P "^\s+$i\t")
26789                         echo "$count stripes created on MDT$i"
26790                         # deviation should < 5% of average
26791                         delta=$((count - total / MDSCOUNT))
26792                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26793                                 error "stripes are not evenly distributed"
26794                 fi
26795         done
26796
26797         echo
26798         echo "Check for uneven MDTs: "
26799
26800         local ffree
26801         local bavail
26802         local max
26803         local min
26804         local max_index
26805         local min_index
26806         local tmp
26807
26808         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26809         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26810         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26811
26812         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26813         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26814         max_index=0
26815         min_index=0
26816         for ((i = 1; i < ${#ffree[@]}; i++)); do
26817                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26818                 if [ $tmp -gt $max ]; then
26819                         max=$tmp
26820                         max_index=$i
26821                 fi
26822                 if [ $tmp -lt $min ]; then
26823                         min=$tmp
26824                         min_index=$i
26825                 fi
26826         done
26827         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26828
26829         (( min > 0 )) || skip "low space on MDT$min_index"
26830         (( ${ffree[min_index]} < 10000000 )) ||
26831                 skip "too many free files on MDT$min_index"
26832
26833         generate_uneven_mdts 120
26834
26835         echo "MDT filesfree available: ${ffree[*]}"
26836         echo "MDT blocks available: ${bavail[*]}"
26837         echo "weight diff=$(((max - min) * 100 / min))%"
26838         echo
26839         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26840
26841         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26842         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26843         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26844         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26845         # decrease statfs age, so that it can be updated in time
26846         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26847         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26848
26849         sleep 1
26850
26851         testdir=$DIR/$tdir-s$stripe_count/qos
26852
26853         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26854         for (( i = 0; i < total / stripe_count; i++ )); do
26855                 eval $mkdir_cmd $testdir/subdir$i ||
26856                         error "$mkdir_cmd subdir$i failed"
26857         done
26858
26859         max=0
26860         for (( i = 0; i < $MDSCOUNT; i++ )); do
26861                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26862                 (( count > max )) && max=$count
26863                 echo "$count directories created on MDT$i : curmax=$max"
26864         done
26865
26866         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26867
26868         # D-value should > 10% of average
26869         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26870                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26871
26872         # ditto for stripes
26873         if (( stripe_count > 1 )); then
26874                 max=0
26875                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26876                         count=$($LFS getdirstripe $testdir/* |
26877                                 grep -c -P "^\s+$i\t")
26878                         (( count > max )) && max=$count
26879                         echo "$count stripes created on MDT$i"
26880                 done
26881
26882                 min=$($LFS getdirstripe $testdir/* |
26883                         grep -c -P "^\s+$min_index\t")
26884                 (( max - min > total / MDSCOUNT / 10 )) ||
26885                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26886         fi
26887 }
26888
26889 most_full_mdt() {
26890         local ffree
26891         local bavail
26892         local bsize
26893         local min
26894         local min_index
26895         local tmp
26896
26897         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26898         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26899         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26900
26901         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26902         min_index=0
26903         for ((i = 1; i < ${#ffree[@]}; i++)); do
26904                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26905                 (( tmp < min )) && min=$tmp && min_index=$i
26906         done
26907
26908         echo -n $min_index
26909 }
26910
26911 test_413a() {
26912         [ $MDSCOUNT -lt 2 ] &&
26913                 skip "We need at least 2 MDTs for this test"
26914
26915         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26916                 skip "Need server version at least 2.12.52"
26917
26918         local stripe_max=$((MDSCOUNT - 1))
26919         local stripe_count
26920
26921         # let caller set maxage for latest result
26922         set_maxage 1
26923
26924         # fill MDT unevenly
26925         generate_uneven_mdts 120
26926
26927         # test 4-stripe directory at most, otherwise it's too slow
26928         # We are being very defensive. Although Autotest uses 4 MDTs.
26929         # We make sure stripe_max does not go over 4.
26930         (( stripe_max > 4 )) && stripe_max=4
26931         # unlinking striped directory is slow on zfs, and may timeout, only test
26932         # plain directory
26933         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26934         for stripe_count in $(seq 1 $stripe_max); do
26935                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26936                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26937                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26938                         error "mkdir failed"
26939                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26940         done
26941 }
26942 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26943
26944 test_413b() {
26945         [ $MDSCOUNT -lt 2 ] &&
26946                 skip "We need at least 2 MDTs for this test"
26947
26948         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26949                 skip "Need server version at least 2.12.52"
26950
26951         local stripe_max=$((MDSCOUNT - 1))
26952         local testdir
26953         local stripe_count
26954
26955         # let caller set maxage for latest result
26956         set_maxage 1
26957
26958         # fill MDT unevenly
26959         generate_uneven_mdts 120
26960
26961         # test 4-stripe directory at most, otherwise it's too slow
26962         # We are being very defensive. Although Autotest uses 4 MDTs.
26963         # We make sure stripe_max does not go over 4.
26964         (( stripe_max > 4 )) && stripe_max=4
26965         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26966         for stripe_count in $(seq 1 $stripe_max); do
26967                 testdir=$DIR/$tdir-s$stripe_count
26968                 mkdir $testdir || error "mkdir $testdir failed"
26969                 mkdir $testdir/rr || error "mkdir rr failed"
26970                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26971                         error "mkdir qos failed"
26972                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26973                         $testdir/rr || error "setdirstripe rr failed"
26974                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26975                         error "setdirstripe failed"
26976                 test_qos_mkdir "mkdir" $stripe_count
26977         done
26978 }
26979 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26980
26981 test_413c() {
26982         (( $MDSCOUNT >= 2 )) ||
26983                 skip "We need at least 2 MDTs for this test"
26984
26985         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26986                 skip "Need server version at least 2.14.51"
26987
26988         local testdir
26989         local inherit
26990         local inherit_rr
26991         local lmv_qos_maxage
26992         local lod_qos_maxage
26993
26994         # let caller set maxage for latest result
26995         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26996         $LCTL set_param lmv.*.qos_maxage=1
26997         stack_trap "$LCTL set_param \
26998                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26999         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27000                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27001         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27002                 lod.*.mdt_qos_maxage=1
27003         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27004                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27005
27006         # fill MDT unevenly
27007         generate_uneven_mdts 120
27008
27009         testdir=$DIR/${tdir}-s1
27010         mkdir $testdir || error "mkdir $testdir failed"
27011         mkdir $testdir/rr || error "mkdir rr failed"
27012         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27013         # default max_inherit is -1, default max_inherit_rr is 0
27014         $LFS setdirstripe -D -c 1 $testdir/rr ||
27015                 error "setdirstripe rr failed"
27016         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27017                 error "setdirstripe qos failed"
27018         test_qos_mkdir "mkdir" 1
27019
27020         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27021         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27022         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27023         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27024         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27025
27026         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27027         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27028         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27029         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27030         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27031         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27032         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27033                 error "level2 shouldn't have default LMV" || true
27034 }
27035 run_test 413c "mkdir with default LMV max inherit rr"
27036
27037 test_413d() {
27038         (( MDSCOUNT >= 2 )) ||
27039                 skip "We need at least 2 MDTs for this test"
27040
27041         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27042                 skip "Need server version at least 2.14.51"
27043
27044         local lmv_qos_threshold_rr
27045
27046         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27047                 head -n1)
27048         stack_trap "$LCTL set_param \
27049                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27050
27051         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27052         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27053         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27054                 error "$tdir shouldn't have default LMV"
27055         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27056                 error "mkdir sub failed"
27057
27058         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27059
27060         (( count == 100 )) || error "$count subdirs on MDT0"
27061 }
27062 run_test 413d "inherit ROOT default LMV"
27063
27064 test_413e() {
27065         (( MDSCOUNT >= 2 )) ||
27066                 skip "We need at least 2 MDTs for this test"
27067         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27068                 skip "Need server version at least 2.14.55"
27069
27070         local testdir=$DIR/$tdir
27071         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27072         local max_inherit
27073         local sub_max_inherit
27074
27075         mkdir -p $testdir || error "failed to create $testdir"
27076
27077         # set default max-inherit to -1 if stripe count is 0 or 1
27078         $LFS setdirstripe -D -c 1 $testdir ||
27079                 error "failed to set default LMV"
27080         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27081         (( max_inherit == -1 )) ||
27082                 error "wrong max_inherit value $max_inherit"
27083
27084         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27085         $LFS setdirstripe -D -c -1 $testdir ||
27086                 error "failed to set default LMV"
27087         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27088         (( max_inherit > 0 )) ||
27089                 error "wrong max_inherit value $max_inherit"
27090
27091         # and the subdir will decrease the max_inherit by 1
27092         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27093         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27094         (( sub_max_inherit == max_inherit - 1)) ||
27095                 error "wrong max-inherit of subdir $sub_max_inherit"
27096
27097         # check specified --max-inherit and warning message
27098         stack_trap "rm -f $tmpfile"
27099         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27100                 error "failed to set default LMV"
27101         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27102         (( max_inherit == -1 )) ||
27103                 error "wrong max_inherit value $max_inherit"
27104
27105         # check the warning messages
27106         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27107                 error "failed to detect warning string"
27108         fi
27109 }
27110 run_test 413e "check default max-inherit value"
27111
27112 test_fs_dmv_inherit()
27113 {
27114         local testdir=$DIR/$tdir
27115
27116         local count
27117         local inherit
27118         local inherit_rr
27119
27120         for i in 1 2; do
27121                 mkdir $testdir || error "mkdir $testdir failed"
27122                 count=$($LFS getdirstripe -D -c $testdir)
27123                 (( count == 1 )) ||
27124                         error "$testdir default LMV count mismatch $count != 1"
27125                 inherit=$($LFS getdirstripe -D -X $testdir)
27126                 (( inherit == 3 - i )) ||
27127                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27128                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27129                 (( inherit_rr == 3 - i )) ||
27130                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27131                 testdir=$testdir/sub
27132         done
27133
27134         mkdir $testdir || error "mkdir $testdir failed"
27135         count=$($LFS getdirstripe -D -c $testdir)
27136         (( count == 0 )) ||
27137                 error "$testdir default LMV count not zero: $count"
27138 }
27139
27140 test_413f() {
27141         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27142
27143         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27144                 skip "Need server version at least 2.14.55"
27145
27146         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27147                 error "dump $DIR default LMV failed"
27148         stack_trap "setfattr --restore=$TMP/dmv.ea"
27149
27150         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27151                 error "set $DIR default LMV failed"
27152
27153         test_fs_dmv_inherit
27154 }
27155 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27156
27157 test_413g() {
27158         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27159
27160         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27161         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27162                 error "dump $DIR default LMV failed"
27163         stack_trap "setfattr --restore=$TMP/dmv.ea"
27164
27165         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27166                 error "set $DIR default LMV failed"
27167
27168         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27169                 error "mount $MOUNT2 failed"
27170         stack_trap "umount_client $MOUNT2"
27171
27172         local saved_DIR=$DIR
27173
27174         export DIR=$MOUNT2
27175
27176         stack_trap "export DIR=$saved_DIR"
27177
27178         # first check filesystem-wide default LMV inheritance
27179         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27180
27181         # then check subdirs are spread to all MDTs
27182         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27183
27184         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27185
27186         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27187 }
27188 run_test 413g "enforce ROOT default LMV on subdir mount"
27189
27190 test_413h() {
27191         (( MDSCOUNT >= 2 )) ||
27192                 skip "We need at least 2 MDTs for this test"
27193
27194         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27195                 skip "Need server version at least 2.15.50.6"
27196
27197         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27198
27199         stack_trap "$LCTL set_param \
27200                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27201         $LCTL set_param lmv.*.qos_maxage=1
27202
27203         local depth=5
27204         local rr_depth=4
27205         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27206         local count=$((MDSCOUNT * 20))
27207
27208         generate_uneven_mdts 50
27209
27210         mkdir -p $dir || error "mkdir $dir failed"
27211         stack_trap "rm -rf $dir"
27212         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27213                 --max-inherit-rr=$rr_depth $dir
27214
27215         for ((d=0; d < depth + 2; d++)); do
27216                 log "dir=$dir:"
27217                 for ((sub=0; sub < count; sub++)); do
27218                         mkdir $dir/d$sub
27219                 done
27220                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27221                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27222                 # subdirs within $rr_depth should be created round-robin
27223                 if (( d < rr_depth )); then
27224                         (( ${num[0]} != count )) ||
27225                                 error "all objects created on MDT ${num[1]}"
27226                 fi
27227
27228                 dir=$dir/d0
27229         done
27230 }
27231 run_test 413h "don't stick to parent for round-robin dirs"
27232
27233 test_413i() {
27234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27235
27236         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27237                 skip "Need server version at least 2.14.55"
27238
27239         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27240                 error "dump $DIR default LMV failed"
27241         stack_trap "setfattr --restore=$TMP/dmv.ea"
27242
27243         local testdir=$DIR/$tdir
27244         local def_max_rr=1
27245         local def_max=3
27246         local count
27247
27248         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27249                 --max-inherit-rr=$def_max_rr $DIR ||
27250                 error "set $DIR default LMV failed"
27251
27252         for i in $(seq 2 3); do
27253                 def_max=$((def_max - 1))
27254                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27255
27256                 mkdir $testdir
27257                 # RR is decremented and keeps zeroed once exhausted
27258                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27259                 (( count == def_max_rr )) ||
27260                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27261
27262                 # max-inherit is decremented
27263                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27264                 (( count == def_max )) ||
27265                         error_noexit "$testdir: max-inherit $count != $def_max"
27266
27267                 testdir=$testdir/d$i
27268         done
27269
27270         # d3 is the last inherited from ROOT, no inheritance anymore
27271         # i.e. no the default layout anymore
27272         mkdir -p $testdir/d4/d5
27273         count=$($LFS getdirstripe -D --max-inherit $testdir)
27274         (( count == -1 )) ||
27275                 error_noexit "$testdir: max-inherit $count != -1"
27276
27277         local p_count=$($LFS getdirstripe -i $testdir)
27278
27279         for i in $(seq 4 5); do
27280                 testdir=$testdir/d$i
27281
27282                 # the root default layout is not applied once exhausted
27283                 count=$($LFS getdirstripe -i $testdir)
27284                 (( count == p_count )) ||
27285                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27286         done
27287
27288         $LFS setdirstripe -i 0 $DIR/d2
27289         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27290         (( count == -1 )) ||
27291                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27292 }
27293 run_test 413i "check default layout inheritance"
27294
27295 test_413z() {
27296         local pids=""
27297         local subdir
27298         local pid
27299
27300         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27301                 unlinkmany $subdir/f. $TEST413_COUNT &
27302                 pids="$pids $!"
27303         done
27304
27305         for pid in $pids; do
27306                 wait $pid
27307         done
27308
27309         true
27310 }
27311 run_test 413z "413 test cleanup"
27312
27313 test_414() {
27314 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27315         $LCTL set_param fail_loc=0x80000521
27316         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27317         rm -f $DIR/$tfile
27318 }
27319 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27320
27321 test_415() {
27322         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27323         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27324                 skip "Need server version at least 2.11.52"
27325
27326         # LU-11102
27327         local total=500
27328         local max=120
27329
27330         # this test may be slow on ZFS
27331         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27332
27333         # though this test is designed for striped directory, let's test normal
27334         # directory too since lock is always saved as CoS lock.
27335         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27336         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27337         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27338         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27339         wait_delete_completed_mds
27340
27341         # run a loop without concurrent touch to measure rename duration.
27342         # only for test debug/robustness, NOT part of COS functional test.
27343         local start_time=$SECONDS
27344         for ((i = 0; i < total; i++)); do
27345                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27346                         > /dev/null
27347         done
27348         local baseline=$((SECONDS - start_time))
27349         echo "rename $total files without 'touch' took $baseline sec"
27350
27351         (
27352                 while true; do
27353                         touch $DIR/$tdir
27354                 done
27355         ) &
27356         local setattr_pid=$!
27357
27358         # rename files back to original name so unlinkmany works
27359         start_time=$SECONDS
27360         for ((i = 0; i < total; i++)); do
27361                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27362                         > /dev/null
27363         done
27364         local duration=$((SECONDS - start_time))
27365
27366         kill -9 $setattr_pid
27367
27368         echo "rename $total files with 'touch' took $duration sec"
27369         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27370         (( duration <= max )) ||
27371                 error_not_in_vm "rename took $duration > $max sec"
27372 }
27373 run_test 415 "lock revoke is not missing"
27374
27375 test_416() {
27376         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27377                 skip "Need server version at least 2.11.55"
27378
27379         # define OBD_FAIL_OSD_TXN_START    0x19a
27380         do_facet mds1 lctl set_param fail_loc=0x19a
27381
27382         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27383
27384         true
27385 }
27386 run_test 416 "transaction start failure won't cause system hung"
27387
27388 cleanup_417() {
27389         trap 0
27390         do_nodes $(comma_list $(mdts_nodes)) \
27391                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27392         do_nodes $(comma_list $(mdts_nodes)) \
27393                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27394         do_nodes $(comma_list $(mdts_nodes)) \
27395                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27396 }
27397
27398 test_417() {
27399         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27400         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27401                 skip "Need MDS version at least 2.11.56"
27402
27403         trap cleanup_417 RETURN EXIT
27404
27405         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27406         do_nodes $(comma_list $(mdts_nodes)) \
27407                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27408         $LFS migrate -m 0 $DIR/$tdir.1 &&
27409                 error "migrate dir $tdir.1 should fail"
27410
27411         do_nodes $(comma_list $(mdts_nodes)) \
27412                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27413         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27414                 error "create remote dir $tdir.2 should fail"
27415
27416         do_nodes $(comma_list $(mdts_nodes)) \
27417                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27418         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27419                 error "create striped dir $tdir.3 should fail"
27420         true
27421 }
27422 run_test 417 "disable remote dir, striped dir and dir migration"
27423
27424 # Checks that the outputs of df [-i] and lfs df [-i] match
27425 #
27426 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27427 check_lfs_df() {
27428         local dir=$2
27429         local inodes
27430         local df_out
27431         local lfs_df_out
27432         local count
27433         local passed=false
27434
27435         # blocks or inodes
27436         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27437
27438         for count in {1..100}; do
27439                 do_nodes "$CLIENTS" \
27440                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27441                 sync; sleep 0.2
27442
27443                 # read the lines of interest
27444                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27445                         error "df $inodes $dir | tail -n +2 failed"
27446                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27447                         error "lfs df $inodes $dir | grep summary: failed"
27448
27449                 # skip first substrings of each output as they are different
27450                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27451                 # compare the two outputs
27452                 passed=true
27453                 #  skip "available" on MDT until LU-13997 is fixed.
27454                 #for i in {1..5}; do
27455                 for i in 1 2 4 5; do
27456                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27457                 done
27458                 $passed && break
27459         done
27460
27461         if ! $passed; then
27462                 df -P $inodes $dir
27463                 echo
27464                 lfs df $inodes $dir
27465                 error "df and lfs df $1 output mismatch: "      \
27466                       "df ${inodes}: ${df_out[*]}, "            \
27467                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27468         fi
27469 }
27470
27471 test_418() {
27472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27473
27474         local dir=$DIR/$tdir
27475         local numfiles=$((RANDOM % 4096 + 2))
27476         local numblocks=$((RANDOM % 256 + 1))
27477
27478         wait_delete_completed
27479         test_mkdir $dir
27480
27481         # check block output
27482         check_lfs_df blocks $dir
27483         # check inode output
27484         check_lfs_df inodes $dir
27485
27486         # create a single file and retest
27487         echo "Creating a single file and testing"
27488         createmany -o $dir/$tfile- 1 &>/dev/null ||
27489                 error "creating 1 file in $dir failed"
27490         check_lfs_df blocks $dir
27491         check_lfs_df inodes $dir
27492
27493         # create a random number of files
27494         echo "Creating $((numfiles - 1)) files and testing"
27495         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27496                 error "creating $((numfiles - 1)) files in $dir failed"
27497
27498         # write a random number of blocks to the first test file
27499         echo "Writing $numblocks 4K blocks and testing"
27500         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27501                 count=$numblocks &>/dev/null ||
27502                 error "dd to $dir/${tfile}-0 failed"
27503
27504         # retest
27505         check_lfs_df blocks $dir
27506         check_lfs_df inodes $dir
27507
27508         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27509                 error "unlinking $numfiles files in $dir failed"
27510 }
27511 run_test 418 "df and lfs df outputs match"
27512
27513 test_419()
27514 {
27515         local dir=$DIR/$tdir
27516
27517         mkdir -p $dir
27518         touch $dir/file
27519
27520         cancel_lru_locks mdc
27521
27522         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27523         $LCTL set_param fail_loc=0x1410
27524         cat $dir/file
27525         $LCTL set_param fail_loc=0
27526         rm -rf $dir
27527 }
27528 run_test 419 "Verify open file by name doesn't crash kernel"
27529
27530 test_420()
27531 {
27532         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27533                 skip "Need MDS version at least 2.12.53"
27534
27535         local SAVE_UMASK=$(umask)
27536         local dir=$DIR/$tdir
27537         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27538
27539         mkdir -p $dir
27540         umask 0000
27541         mkdir -m03777 $dir/testdir
27542         ls -dn $dir/testdir
27543         # Need to remove trailing '.' when SELinux is enabled
27544         local dirperms=$(ls -dn $dir/testdir |
27545                          awk '{ sub(/\.$/, "", $1); print $1}')
27546         [ $dirperms == "drwxrwsrwt" ] ||
27547                 error "incorrect perms on $dir/testdir"
27548
27549         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27550                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27551         ls -n $dir/testdir/testfile
27552         local fileperms=$(ls -n $dir/testdir/testfile |
27553                           awk '{ sub(/\.$/, "", $1); print $1}')
27554         [ $fileperms == "-rwxr-xr-x" ] ||
27555                 error "incorrect perms on $dir/testdir/testfile"
27556
27557         umask $SAVE_UMASK
27558 }
27559 run_test 420 "clear SGID bit on non-directories for non-members"
27560
27561 test_421a() {
27562         local cnt
27563         local fid1
27564         local fid2
27565
27566         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27567                 skip "Need MDS version at least 2.12.54"
27568
27569         test_mkdir $DIR/$tdir
27570         createmany -o $DIR/$tdir/f 3
27571         cnt=$(ls -1 $DIR/$tdir | wc -l)
27572         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27573
27574         fid1=$(lfs path2fid $DIR/$tdir/f1)
27575         fid2=$(lfs path2fid $DIR/$tdir/f2)
27576         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27577
27578         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27579         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27580
27581         cnt=$(ls -1 $DIR/$tdir | wc -l)
27582         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27583
27584         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27585         createmany -o $DIR/$tdir/f 3
27586         cnt=$(ls -1 $DIR/$tdir | wc -l)
27587         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27588
27589         fid1=$(lfs path2fid $DIR/$tdir/f1)
27590         fid2=$(lfs path2fid $DIR/$tdir/f2)
27591         echo "remove using fsname $FSNAME"
27592         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27593
27594         cnt=$(ls -1 $DIR/$tdir | wc -l)
27595         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27596 }
27597 run_test 421a "simple rm by fid"
27598
27599 test_421b() {
27600         local cnt
27601         local FID1
27602         local FID2
27603
27604         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27605                 skip "Need MDS version at least 2.12.54"
27606
27607         test_mkdir $DIR/$tdir
27608         createmany -o $DIR/$tdir/f 3
27609         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27610         MULTIPID=$!
27611
27612         FID1=$(lfs path2fid $DIR/$tdir/f1)
27613         FID2=$(lfs path2fid $DIR/$tdir/f2)
27614         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27615
27616         kill -USR1 $MULTIPID
27617         wait
27618
27619         cnt=$(ls $DIR/$tdir | wc -l)
27620         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27621 }
27622 run_test 421b "rm by fid on open file"
27623
27624 test_421c() {
27625         local cnt
27626         local FIDS
27627
27628         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27629                 skip "Need MDS version at least 2.12.54"
27630
27631         test_mkdir $DIR/$tdir
27632         createmany -o $DIR/$tdir/f 3
27633         touch $DIR/$tdir/$tfile
27634         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27635         cnt=$(ls -1 $DIR/$tdir | wc -l)
27636         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27637
27638         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27639         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27640
27641         cnt=$(ls $DIR/$tdir | wc -l)
27642         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27643 }
27644 run_test 421c "rm by fid against hardlinked files"
27645
27646 test_421d() {
27647         local cnt
27648         local FIDS
27649
27650         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27651                 skip "Need MDS version at least 2.12.54"
27652
27653         test_mkdir $DIR/$tdir
27654         createmany -o $DIR/$tdir/f 4097
27655         cnt=$(ls -1 $DIR/$tdir | wc -l)
27656         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27657
27658         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27659         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27660
27661         cnt=$(ls $DIR/$tdir | wc -l)
27662         rm -rf $DIR/$tdir
27663         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27664 }
27665 run_test 421d "rmfid en masse"
27666
27667 test_421e() {
27668         local cnt
27669         local FID
27670
27671         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27672         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27673                 skip "Need MDS version at least 2.12.54"
27674
27675         mkdir -p $DIR/$tdir
27676         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27677         createmany -o $DIR/$tdir/striped_dir/f 512
27678         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27679         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27680
27681         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27682                 sed "s/[/][^:]*://g")
27683         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27684
27685         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27686         rm -rf $DIR/$tdir
27687         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27688 }
27689 run_test 421e "rmfid in DNE"
27690
27691 test_421f() {
27692         local cnt
27693         local FID
27694
27695         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27696                 skip "Need MDS version at least 2.12.54"
27697
27698         test_mkdir $DIR/$tdir
27699         touch $DIR/$tdir/f
27700         cnt=$(ls -1 $DIR/$tdir | wc -l)
27701         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27702
27703         FID=$(lfs path2fid $DIR/$tdir/f)
27704         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27705         # rmfid should fail
27706         cnt=$(ls -1 $DIR/$tdir | wc -l)
27707         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27708
27709         chmod a+rw $DIR/$tdir
27710         ls -la $DIR/$tdir
27711         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27712         # rmfid should fail
27713         cnt=$(ls -1 $DIR/$tdir | wc -l)
27714         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27715
27716         rm -f $DIR/$tdir/f
27717         $RUNAS touch $DIR/$tdir/f
27718         FID=$(lfs path2fid $DIR/$tdir/f)
27719         echo "rmfid as root"
27720         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27721         cnt=$(ls -1 $DIR/$tdir | wc -l)
27722         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27723
27724         rm -f $DIR/$tdir/f
27725         $RUNAS touch $DIR/$tdir/f
27726         cnt=$(ls -1 $DIR/$tdir | wc -l)
27727         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27728         FID=$(lfs path2fid $DIR/$tdir/f)
27729         # rmfid w/o user_fid2path mount option should fail
27730         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27731         cnt=$(ls -1 $DIR/$tdir | wc -l)
27732         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27733
27734         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27735         stack_trap "rmdir $tmpdir"
27736         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27737                 error "failed to mount client'"
27738         stack_trap "umount_client $tmpdir"
27739
27740         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27741         # rmfid should succeed
27742         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27743         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27744
27745         # rmfid shouldn't allow to remove files due to dir's permission
27746         chmod a+rwx $tmpdir/$tdir
27747         touch $tmpdir/$tdir/f
27748         ls -la $tmpdir/$tdir
27749         FID=$(lfs path2fid $tmpdir/$tdir/f)
27750         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27751         return 0
27752 }
27753 run_test 421f "rmfid checks permissions"
27754
27755 test_421g() {
27756         local cnt
27757         local FIDS
27758
27759         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27760         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27761                 skip "Need MDS version at least 2.12.54"
27762
27763         mkdir -p $DIR/$tdir
27764         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27765         createmany -o $DIR/$tdir/striped_dir/f 512
27766         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27767         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27768
27769         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27770                 sed "s/[/][^:]*://g")
27771
27772         rm -f $DIR/$tdir/striped_dir/f1*
27773         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27774         removed=$((512 - cnt))
27775
27776         # few files have been just removed, so we expect
27777         # rmfid to fail on their fids
27778         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27779         [ $removed != $errors ] && error "$errors != $removed"
27780
27781         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27782         rm -rf $DIR/$tdir
27783         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27784 }
27785 run_test 421g "rmfid to return errors properly"
27786
27787 test_421h() {
27788         local mount_other
27789         local mount_ret
27790         local rmfid_ret
27791         local old_fid
27792         local fidA
27793         local fidB
27794         local fidC
27795         local fidD
27796
27797         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27798                 skip "Need MDS version at least 2.15.53"
27799
27800         test_mkdir $DIR/$tdir
27801         test_mkdir $DIR/$tdir/subdir
27802         touch $DIR/$tdir/subdir/file0
27803         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27804         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27805         rm -f $DIR/$tdir/subdir/file0
27806         touch $DIR/$tdir/subdir/fileA
27807         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27808         echo File $DIR/$tdir/subdir/fileA FID $fidA
27809         touch $DIR/$tdir/subdir/fileB
27810         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27811         echo File $DIR/$tdir/subdir/fileB FID $fidB
27812         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27813         touch $DIR/$tdir/subdir/fileC
27814         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27815         echo File $DIR/$tdir/subdir/fileC FID $fidC
27816         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27817         touch $DIR/$tdir/fileD
27818         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27819         echo File $DIR/$tdir/fileD FID $fidD
27820
27821         # mount another client mount point with subdirectory mount
27822         export FILESET=/$tdir/subdir
27823         mount_other=${MOUNT}_other
27824         mount_client $mount_other ${MOUNT_OPTS}
27825         mount_ret=$?
27826         export FILESET=""
27827         (( mount_ret == 0 )) || error "mount $mount_other failed"
27828
27829         echo Removing FIDs:
27830         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27831         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27832         rmfid_ret=$?
27833
27834         umount_client $mount_other || error "umount $mount_other failed"
27835
27836         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27837
27838         # fileA should have been deleted
27839         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27840
27841         # fileB should have been deleted
27842         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27843
27844         # fileC should not have been deleted, fid also exists outside of fileset
27845         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27846
27847         # fileD should not have been deleted, it exists outside of fileset
27848         stat $DIR/$tdir/fileD || error "fileD deleted"
27849 }
27850 run_test 421h "rmfid with fileset mount"
27851
27852 test_422() {
27853         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27854         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27855         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27856         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27857         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27858
27859         local amc=$(at_max_get client)
27860         local amo=$(at_max_get mds1)
27861         local timeout=`lctl get_param -n timeout`
27862
27863         at_max_set 0 client
27864         at_max_set 0 mds1
27865
27866 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27867         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27868                         fail_val=$(((2*timeout + 10)*1000))
27869         touch $DIR/$tdir/d3/file &
27870         sleep 2
27871 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27872         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27873                         fail_val=$((2*timeout + 5))
27874         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27875         local pid=$!
27876         sleep 1
27877         kill -9 $pid
27878         sleep $((2 * timeout))
27879         echo kill $pid
27880         kill -9 $pid
27881         lctl mark touch
27882         touch $DIR/$tdir/d2/file3
27883         touch $DIR/$tdir/d2/file4
27884         touch $DIR/$tdir/d2/file5
27885
27886         wait
27887         at_max_set $amc client
27888         at_max_set $amo mds1
27889
27890         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27891         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27892                 error "Watchdog is always throttled"
27893 }
27894 run_test 422 "kill a process with RPC in progress"
27895
27896 stat_test() {
27897     df -h $MOUNT &
27898     df -h $MOUNT &
27899     df -h $MOUNT &
27900     df -h $MOUNT &
27901     df -h $MOUNT &
27902     df -h $MOUNT &
27903 }
27904
27905 test_423() {
27906     local _stats
27907     # ensure statfs cache is expired
27908     sleep 2;
27909
27910     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27911     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27912
27913     return 0
27914 }
27915 run_test 423 "statfs should return a right data"
27916
27917 test_424() {
27918 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27919         $LCTL set_param fail_loc=0x80000522
27920         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27921         rm -f $DIR/$tfile
27922 }
27923 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27924
27925 test_425() {
27926         test_mkdir -c -1 $DIR/$tdir
27927         $LFS setstripe -c -1 $DIR/$tdir
27928
27929         lru_resize_disable "" 100
27930         stack_trap "lru_resize_enable" EXIT
27931
27932         sleep 5
27933
27934         for i in $(seq $((MDSCOUNT * 125))); do
27935                 local t=$DIR/$tdir/$tfile_$i
27936
27937                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27938                         error_noexit "Create file $t"
27939         done
27940         stack_trap "rm -rf $DIR/$tdir" EXIT
27941
27942         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27943                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27944                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27945
27946                 [ $lock_count -le $lru_size ] ||
27947                         error "osc lock count $lock_count > lru size $lru_size"
27948         done
27949
27950         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27951                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27952                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27953
27954                 [ $lock_count -le $lru_size ] ||
27955                         error "mdc lock count $lock_count > lru size $lru_size"
27956         done
27957 }
27958 run_test 425 "lock count should not exceed lru size"
27959
27960 test_426() {
27961         splice-test -r $DIR/$tfile
27962         splice-test -rd $DIR/$tfile
27963         splice-test $DIR/$tfile
27964         splice-test -d $DIR/$tfile
27965 }
27966 run_test 426 "splice test on Lustre"
27967
27968 test_427() {
27969         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27970         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27971                 skip "Need MDS version at least 2.12.4"
27972         local log
27973
27974         mkdir $DIR/$tdir
27975         mkdir $DIR/$tdir/1
27976         mkdir $DIR/$tdir/2
27977         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27978         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27979
27980         $LFS getdirstripe $DIR/$tdir/1/dir
27981
27982         #first setfattr for creating updatelog
27983         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27984
27985 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27986         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27987         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27988         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27989
27990         sleep 2
27991         fail mds2
27992         wait_recovery_complete mds2 $((2*TIMEOUT))
27993
27994         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27995         echo $log | grep "get update log failed" &&
27996                 error "update log corruption is detected" || true
27997 }
27998 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27999
28000 test_428() {
28001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28002         local cache_limit=$CACHE_MAX
28003
28004         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28005         $LCTL set_param -n llite.*.max_cached_mb=64
28006
28007         mkdir $DIR/$tdir
28008         $LFS setstripe -c 1 $DIR/$tdir
28009         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28010         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28011         #test write
28012         for f in $(seq 4); do
28013                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28014         done
28015         wait
28016
28017         cancel_lru_locks osc
28018         # Test read
28019         for f in $(seq 4); do
28020                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28021         done
28022         wait
28023 }
28024 run_test 428 "large block size IO should not hang"
28025
28026 test_429() { # LU-7915 / LU-10948
28027         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28028         local testfile=$DIR/$tfile
28029         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28030         local new_flag=1
28031         local first_rpc
28032         local second_rpc
28033         local third_rpc
28034
28035         $LCTL get_param $ll_opencache_threshold_count ||
28036                 skip "client does not have opencache parameter"
28037
28038         set_opencache $new_flag
28039         stack_trap "restore_opencache"
28040         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28041                 error "enable opencache failed"
28042         touch $testfile
28043         # drop MDC DLM locks
28044         cancel_lru_locks mdc
28045         # clear MDC RPC stats counters
28046         $LCTL set_param $mdc_rpcstats=clear
28047
28048         # According to the current implementation, we need to run 3 times
28049         # open & close file to verify if opencache is enabled correctly.
28050         # 1st, RPCs are sent for lookup/open and open handle is released on
28051         #      close finally.
28052         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28053         #      so open handle won't be released thereafter.
28054         # 3rd, No RPC is sent out.
28055         $MULTIOP $testfile oc || error "multiop failed"
28056         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28057         echo "1st: $first_rpc RPCs in flight"
28058
28059         $MULTIOP $testfile oc || error "multiop failed"
28060         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28061         echo "2nd: $second_rpc RPCs in flight"
28062
28063         $MULTIOP $testfile oc || error "multiop failed"
28064         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28065         echo "3rd: $third_rpc RPCs in flight"
28066
28067         #verify no MDC RPC is sent
28068         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28069 }
28070 run_test 429 "verify if opencache flag on client side does work"
28071
28072 lseek_test_430() {
28073         local offset
28074         local file=$1
28075
28076         # data at [200K, 400K)
28077         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28078                 error "256K->512K dd fails"
28079         # data at [2M, 3M)
28080         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28081                 error "2M->3M dd fails"
28082         # data at [4M, 5M)
28083         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28084                 error "4M->5M dd fails"
28085         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28086         # start at first component hole #1
28087         printf "Seeking hole from 1000 ... "
28088         offset=$(lseek_test -l 1000 $file)
28089         echo $offset
28090         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28091         printf "Seeking data from 1000 ... "
28092         offset=$(lseek_test -d 1000 $file)
28093         echo $offset
28094         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28095
28096         # start at first component data block
28097         printf "Seeking hole from 300000 ... "
28098         offset=$(lseek_test -l 300000 $file)
28099         echo $offset
28100         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28101         printf "Seeking data from 300000 ... "
28102         offset=$(lseek_test -d 300000 $file)
28103         echo $offset
28104         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28105
28106         # start at the first component but beyond end of object size
28107         printf "Seeking hole from 1000000 ... "
28108         offset=$(lseek_test -l 1000000 $file)
28109         echo $offset
28110         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28111         printf "Seeking data from 1000000 ... "
28112         offset=$(lseek_test -d 1000000 $file)
28113         echo $offset
28114         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28115
28116         # start at second component stripe 2 (empty file)
28117         printf "Seeking hole from 1500000 ... "
28118         offset=$(lseek_test -l 1500000 $file)
28119         echo $offset
28120         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28121         printf "Seeking data from 1500000 ... "
28122         offset=$(lseek_test -d 1500000 $file)
28123         echo $offset
28124         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28125
28126         # start at second component stripe 1 (all data)
28127         printf "Seeking hole from 3000000 ... "
28128         offset=$(lseek_test -l 3000000 $file)
28129         echo $offset
28130         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28131         printf "Seeking data from 3000000 ... "
28132         offset=$(lseek_test -d 3000000 $file)
28133         echo $offset
28134         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28135
28136         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28137                 error "2nd dd fails"
28138         echo "Add data block at 640K...1280K"
28139
28140         # start at before new data block, in hole
28141         printf "Seeking hole from 600000 ... "
28142         offset=$(lseek_test -l 600000 $file)
28143         echo $offset
28144         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28145         printf "Seeking data from 600000 ... "
28146         offset=$(lseek_test -d 600000 $file)
28147         echo $offset
28148         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28149
28150         # start at the first component new data block
28151         printf "Seeking hole from 1000000 ... "
28152         offset=$(lseek_test -l 1000000 $file)
28153         echo $offset
28154         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28155         printf "Seeking data from 1000000 ... "
28156         offset=$(lseek_test -d 1000000 $file)
28157         echo $offset
28158         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28159
28160         # start at second component stripe 2, new data
28161         printf "Seeking hole from 1200000 ... "
28162         offset=$(lseek_test -l 1200000 $file)
28163         echo $offset
28164         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28165         printf "Seeking data from 1200000 ... "
28166         offset=$(lseek_test -d 1200000 $file)
28167         echo $offset
28168         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28169
28170         # start beyond file end
28171         printf "Using offset > filesize ... "
28172         lseek_test -l 4000000 $file && error "lseek should fail"
28173         printf "Using offset > filesize ... "
28174         lseek_test -d 4000000 $file && error "lseek should fail"
28175
28176         printf "Done\n\n"
28177 }
28178
28179 test_430a() {
28180         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28181                 skip "MDT does not support SEEK_HOLE"
28182
28183         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28184                 skip "OST does not support SEEK_HOLE"
28185
28186         local file=$DIR/$tdir/$tfile
28187
28188         mkdir -p $DIR/$tdir
28189
28190         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28191         # OST stripe #1 will have continuous data at [1M, 3M)
28192         # OST stripe #2 is empty
28193         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28194         lseek_test_430 $file
28195         rm $file
28196         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28197         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28198         lseek_test_430 $file
28199         rm $file
28200         $LFS setstripe -c2 -S 512K $file
28201         echo "Two stripes, stripe size 512K"
28202         lseek_test_430 $file
28203         rm $file
28204         # FLR with stale mirror
28205         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28206                        -N -c2 -S 1M $file
28207         echo "Mirrored file:"
28208         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28209         echo "Plain 2 stripes 1M"
28210         lseek_test_430 $file
28211         rm $file
28212 }
28213 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28214
28215 test_430b() {
28216         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28217                 skip "OST does not support SEEK_HOLE"
28218
28219         local offset
28220         local file=$DIR/$tdir/$tfile
28221
28222         mkdir -p $DIR/$tdir
28223         # Empty layout lseek should fail
28224         $MCREATE $file
28225         # seek from 0
28226         printf "Seeking hole from 0 ... "
28227         lseek_test -l 0 $file && error "lseek should fail"
28228         printf "Seeking data from 0 ... "
28229         lseek_test -d 0 $file && error "lseek should fail"
28230         rm $file
28231
28232         # 1M-hole file
28233         $LFS setstripe -E 1M -c2 -E eof $file
28234         $TRUNCATE $file 1048576
28235         printf "Seeking hole from 1000000 ... "
28236         offset=$(lseek_test -l 1000000 $file)
28237         echo $offset
28238         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28239         printf "Seeking data from 1000000 ... "
28240         lseek_test -d 1000000 $file && error "lseek should fail"
28241         rm $file
28242
28243         # full component followed by non-inited one
28244         $LFS setstripe -E 1M -c2 -E eof $file
28245         dd if=/dev/urandom of=$file bs=1M count=1
28246         printf "Seeking hole from 1000000 ... "
28247         offset=$(lseek_test -l 1000000 $file)
28248         echo $offset
28249         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28250         printf "Seeking hole from 1048576 ... "
28251         lseek_test -l 1048576 $file && error "lseek should fail"
28252         # init second component and truncate back
28253         echo "123" >> $file
28254         $TRUNCATE $file 1048576
28255         printf "Seeking hole from 1000000 ... "
28256         offset=$(lseek_test -l 1000000 $file)
28257         echo $offset
28258         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28259         printf "Seeking hole from 1048576 ... "
28260         lseek_test -l 1048576 $file && error "lseek should fail"
28261         # boundary checks for big values
28262         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28263         offset=$(lseek_test -d 0 $file.10g)
28264         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28265         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28266         offset=$(lseek_test -d 0 $file.100g)
28267         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28268         return 0
28269 }
28270 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28271
28272 test_430c() {
28273         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28274                 skip "OST does not support SEEK_HOLE"
28275
28276         local file=$DIR/$tdir/$tfile
28277         local start
28278
28279         mkdir -p $DIR/$tdir
28280         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28281
28282         # cp version 8.33+ prefers lseek over fiemap
28283         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28284                 start=$SECONDS
28285                 time cp $file /dev/null
28286                 (( SECONDS - start < 5 )) ||
28287                         error "cp: too long runtime $((SECONDS - start))"
28288
28289         fi
28290         # tar version 1.29+ supports SEEK_HOLE/DATA
28291         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28292                 start=$SECONDS
28293                 time tar cS $file - | cat > /dev/null
28294                 (( SECONDS - start < 5 )) ||
28295                         error "tar: too long runtime $((SECONDS - start))"
28296         fi
28297 }
28298 run_test 430c "lseek: external tools check"
28299
28300 test_431() { # LU-14187
28301         local file=$DIR/$tdir/$tfile
28302
28303         mkdir -p $DIR/$tdir
28304         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28305         dd if=/dev/urandom of=$file bs=4k count=1
28306         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28307         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28308         #define OBD_FAIL_OST_RESTART_IO 0x251
28309         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28310         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28311         cp $file $file.0
28312         cancel_lru_locks
28313         sync_all_data
28314         echo 3 > /proc/sys/vm/drop_caches
28315         diff  $file $file.0 || error "data diff"
28316 }
28317 run_test 431 "Restart transaction for IO"
28318
28319 cleanup_test_432() {
28320         do_facet mgs $LCTL nodemap_activate 0
28321         wait_nm_sync active
28322 }
28323
28324 test_432() {
28325         local tmpdir=$TMP/dir432
28326
28327         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28328                 skip "Need MDS version at least 2.14.52"
28329
28330         stack_trap cleanup_test_432 EXIT
28331         mkdir $DIR/$tdir
28332         mkdir $tmpdir
28333
28334         do_facet mgs $LCTL nodemap_activate 1
28335         wait_nm_sync active
28336         do_facet mgs $LCTL nodemap_modify --name default \
28337                 --property admin --value 1
28338         do_facet mgs $LCTL nodemap_modify --name default \
28339                 --property trusted --value 1
28340         cancel_lru_locks mdc
28341         wait_nm_sync default admin_nodemap
28342         wait_nm_sync default trusted_nodemap
28343
28344         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28345                grep -ci "Operation not permitted") -ne 0 ]; then
28346                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28347         fi
28348 }
28349 run_test 432 "mv dir from outside Lustre"
28350
28351 test_433() {
28352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28353
28354         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28355                 skip "inode cache not supported"
28356
28357         $LCTL set_param llite.*.inode_cache=0
28358         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28359
28360         local count=256
28361         local before
28362         local after
28363
28364         cancel_lru_locks mdc
28365         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28366         createmany -m $DIR/$tdir/f $count
28367         createmany -d $DIR/$tdir/d $count
28368         ls -l $DIR/$tdir > /dev/null
28369         stack_trap "rm -rf $DIR/$tdir"
28370
28371         before=$(num_objects)
28372         cancel_lru_locks mdc
28373         after=$(num_objects)
28374
28375         # sometimes even @before is less than 2 * count
28376         while (( before - after < count )); do
28377                 sleep 1
28378                 after=$(num_objects)
28379                 wait=$((wait + 1))
28380                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28381                 if (( wait > 60 )); then
28382                         error "inode slab grew from $before to $after"
28383                 fi
28384         done
28385
28386         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28387 }
28388 run_test 433 "ldlm lock cancel releases dentries and inodes"
28389
28390 test_434() {
28391         local file
28392         local getxattr_count
28393         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28395
28396         [[ $(getenforce) == "Disabled" ]] ||
28397                 skip "lsm selinux module have to be disabled for this test"
28398
28399         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28400                 error "fail to create $DIR/$tdir/ on MDT0000"
28401
28402         touch $DIR/$tdir/$tfile-{001..100}
28403
28404         # disable the xattr cache
28405         save_lustre_params client "llite.*.xattr_cache" > $p
28406         lctl set_param llite.*.xattr_cache=0
28407         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28408
28409         # clear clients mdc stats
28410         clear_stats $mdc_stat_param ||
28411                 error "fail to clear stats on mdc MDT0000"
28412
28413         for file in $DIR/$tdir/$tfile-{001..100}; do
28414                 getfattr -n security.selinux $file |&
28415                         grep -q "Operation not supported" ||
28416                         error "getxattr on security.selinux should return EOPNOTSUPP"
28417         done
28418
28419         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28420         (( getxattr_count < 100 )) ||
28421                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28422 }
28423 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28424
28425 test_440() {
28426         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28427                 source $LUSTRE/scripts/bash-completion/lustre
28428         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28429                 source /usr/share/bash-completion/completions/lustre
28430         else
28431                 skip "bash completion scripts not found"
28432         fi
28433
28434         local lctl_completions
28435         local lfs_completions
28436
28437         lctl_completions=$(_lustre_cmds lctl)
28438         if [[ ! $lctl_completions =~ "get_param" ]]; then
28439                 error "lctl bash completion failed"
28440         fi
28441
28442         lfs_completions=$(_lustre_cmds lfs)
28443         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28444                 error "lfs bash completion failed"
28445         fi
28446 }
28447 run_test 440 "bash completion for lfs, lctl"
28448
28449 prep_801() {
28450         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28451         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28452                 skip "Need server version at least 2.9.55"
28453
28454         start_full_debug_logging
28455 }
28456
28457 post_801() {
28458         stop_full_debug_logging
28459 }
28460
28461 barrier_stat() {
28462         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28463                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28464                            awk '/The barrier for/ { print $7 }')
28465                 echo $st
28466         else
28467                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28468                 echo \'$st\'
28469         fi
28470 }
28471
28472 barrier_expired() {
28473         local expired
28474
28475         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28476                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28477                           awk '/will be expired/ { print $7 }')
28478         else
28479                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28480         fi
28481
28482         echo $expired
28483 }
28484
28485 test_801a() {
28486         prep_801
28487
28488         echo "Start barrier_freeze at: $(date)"
28489         #define OBD_FAIL_BARRIER_DELAY          0x2202
28490         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28491         # Do not reduce barrier time - See LU-11873
28492         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28493
28494         sleep 2
28495         local b_status=$(barrier_stat)
28496         echo "Got barrier status at: $(date)"
28497         [ "$b_status" = "'freezing_p1'" ] ||
28498                 error "(1) unexpected barrier status $b_status"
28499
28500         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28501         wait
28502         b_status=$(barrier_stat)
28503         [ "$b_status" = "'frozen'" ] ||
28504                 error "(2) unexpected barrier status $b_status"
28505
28506         local expired=$(barrier_expired)
28507         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28508         sleep $((expired + 3))
28509
28510         b_status=$(barrier_stat)
28511         [ "$b_status" = "'expired'" ] ||
28512                 error "(3) unexpected barrier status $b_status"
28513
28514         # Do not reduce barrier time - See LU-11873
28515         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28516                 error "(4) fail to freeze barrier"
28517
28518         b_status=$(barrier_stat)
28519         [ "$b_status" = "'frozen'" ] ||
28520                 error "(5) unexpected barrier status $b_status"
28521
28522         echo "Start barrier_thaw at: $(date)"
28523         #define OBD_FAIL_BARRIER_DELAY          0x2202
28524         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28525         do_facet mgs $LCTL barrier_thaw $FSNAME &
28526
28527         sleep 2
28528         b_status=$(barrier_stat)
28529         echo "Got barrier status at: $(date)"
28530         [ "$b_status" = "'thawing'" ] ||
28531                 error "(6) unexpected barrier status $b_status"
28532
28533         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28534         wait
28535         b_status=$(barrier_stat)
28536         [ "$b_status" = "'thawed'" ] ||
28537                 error "(7) unexpected barrier status $b_status"
28538
28539         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28540         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28541         do_facet mgs $LCTL barrier_freeze $FSNAME
28542
28543         b_status=$(barrier_stat)
28544         [ "$b_status" = "'failed'" ] ||
28545                 error "(8) unexpected barrier status $b_status"
28546
28547         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28548         do_facet mgs $LCTL barrier_thaw $FSNAME
28549
28550         post_801
28551 }
28552 run_test 801a "write barrier user interfaces and stat machine"
28553
28554 test_801b() {
28555         prep_801
28556
28557         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28558         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28559         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28560         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28561         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28562
28563         cancel_lru_locks mdc
28564
28565         # 180 seconds should be long enough
28566         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28567
28568         local b_status=$(barrier_stat)
28569         [ "$b_status" = "'frozen'" ] ||
28570                 error "(6) unexpected barrier status $b_status"
28571
28572         mkdir $DIR/$tdir/d0/d10 &
28573         mkdir_pid=$!
28574
28575         touch $DIR/$tdir/d1/f13 &
28576         touch_pid=$!
28577
28578         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28579         ln_pid=$!
28580
28581         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28582         mv_pid=$!
28583
28584         rm -f $DIR/$tdir/d4/f12 &
28585         rm_pid=$!
28586
28587         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28588
28589         # To guarantee taht the 'stat' is not blocked
28590         b_status=$(barrier_stat)
28591         [ "$b_status" = "'frozen'" ] ||
28592                 error "(8) unexpected barrier status $b_status"
28593
28594         # let above commands to run at background
28595         sleep 5
28596
28597         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28598         ps -p $touch_pid || error "(10) touch should be blocked"
28599         ps -p $ln_pid || error "(11) link should be blocked"
28600         ps -p $mv_pid || error "(12) rename should be blocked"
28601         ps -p $rm_pid || error "(13) unlink should be blocked"
28602
28603         b_status=$(barrier_stat)
28604         [ "$b_status" = "'frozen'" ] ||
28605                 error "(14) unexpected barrier status $b_status"
28606
28607         do_facet mgs $LCTL barrier_thaw $FSNAME
28608         b_status=$(barrier_stat)
28609         [ "$b_status" = "'thawed'" ] ||
28610                 error "(15) unexpected barrier status $b_status"
28611
28612         wait $mkdir_pid || error "(16) mkdir should succeed"
28613         wait $touch_pid || error "(17) touch should succeed"
28614         wait $ln_pid || error "(18) link should succeed"
28615         wait $mv_pid || error "(19) rename should succeed"
28616         wait $rm_pid || error "(20) unlink should succeed"
28617
28618         post_801
28619 }
28620 run_test 801b "modification will be blocked by write barrier"
28621
28622 test_801c() {
28623         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28624
28625         prep_801
28626
28627         stop mds2 || error "(1) Fail to stop mds2"
28628
28629         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28630
28631         local b_status=$(barrier_stat)
28632         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28633                 do_facet mgs $LCTL barrier_thaw $FSNAME
28634                 error "(2) unexpected barrier status $b_status"
28635         }
28636
28637         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28638                 error "(3) Fail to rescan barrier bitmap"
28639
28640         # Do not reduce barrier time - See LU-11873
28641         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28642
28643         b_status=$(barrier_stat)
28644         [ "$b_status" = "'frozen'" ] ||
28645                 error "(4) unexpected barrier status $b_status"
28646
28647         do_facet mgs $LCTL barrier_thaw $FSNAME
28648         b_status=$(barrier_stat)
28649         [ "$b_status" = "'thawed'" ] ||
28650                 error "(5) unexpected barrier status $b_status"
28651
28652         local devname=$(mdsdevname 2)
28653
28654         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28655
28656         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28657                 error "(7) Fail to rescan barrier bitmap"
28658
28659         post_801
28660 }
28661 run_test 801c "rescan barrier bitmap"
28662
28663 test_802b() {
28664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28665         remote_mds_nodsh && skip "remote MDS with nodsh"
28666
28667         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28668                 skip "readonly option not available"
28669
28670         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28671
28672         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28673                 error "(2) Fail to copy"
28674
28675         # write back all cached data before setting MDT to readonly
28676         cancel_lru_locks
28677         sync_all_data
28678
28679         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28680         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28681
28682         echo "Modify should be refused"
28683         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28684
28685         echo "Read should be allowed"
28686         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28687                 error "(7) Read should succeed under ro mode"
28688
28689         # disable readonly
28690         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28691 }
28692 run_test 802b "be able to set MDTs to readonly"
28693
28694 test_803a() {
28695         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28696         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28697                 skip "MDS needs to be newer than 2.10.54"
28698
28699         mkdir_on_mdt0 $DIR/$tdir
28700         # Create some objects on all MDTs to trigger related logs objects
28701         for idx in $(seq $MDSCOUNT); do
28702                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28703                         $DIR/$tdir/dir${idx} ||
28704                         error "Fail to create $DIR/$tdir/dir${idx}"
28705         done
28706
28707         wait_delete_completed # ensure old test cleanups are finished
28708         sleep 3
28709         echo "before create:"
28710         $LFS df -i $MOUNT
28711         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28712
28713         for i in {1..10}; do
28714                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28715                         error "Fail to create $DIR/$tdir/foo$i"
28716         done
28717
28718         # sync ZFS-on-MDS to refresh statfs data
28719         wait_zfs_commit mds1
28720         sleep 3
28721         echo "after create:"
28722         $LFS df -i $MOUNT
28723         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28724
28725         # allow for an llog to be cleaned up during the test
28726         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28727                 error "before ($before_used) + 10 > after ($after_used)"
28728
28729         for i in {1..10}; do
28730                 rm -rf $DIR/$tdir/foo$i ||
28731                         error "Fail to remove $DIR/$tdir/foo$i"
28732         done
28733
28734         # sync ZFS-on-MDS to refresh statfs data
28735         wait_zfs_commit mds1
28736         wait_delete_completed
28737         sleep 3 # avoid MDT return cached statfs
28738         echo "after unlink:"
28739         $LFS df -i $MOUNT
28740         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28741
28742         # allow for an llog to be created during the test
28743         [ $after_used -le $((before_used + 1)) ] ||
28744                 error "after ($after_used) > before ($before_used) + 1"
28745 }
28746 run_test 803a "verify agent object for remote object"
28747
28748 test_803b() {
28749         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28750         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28751                 skip "MDS needs to be newer than 2.13.56"
28752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28753
28754         for i in $(seq 0 $((MDSCOUNT - 1))); do
28755                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28756         done
28757
28758         local before=0
28759         local after=0
28760
28761         local tmp
28762
28763         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28764         for i in $(seq 0 $((MDSCOUNT - 1))); do
28765                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28766                         awk '/getattr/ { print $2 }')
28767                 before=$((before + tmp))
28768         done
28769         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28770         for i in $(seq 0 $((MDSCOUNT - 1))); do
28771                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28772                         awk '/getattr/ { print $2 }')
28773                 after=$((after + tmp))
28774         done
28775
28776         [ $before -eq $after ] || error "getattr count $before != $after"
28777 }
28778 run_test 803b "remote object can getattr from cache"
28779
28780 test_804() {
28781         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28782         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28783                 skip "MDS needs to be newer than 2.10.54"
28784         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28785
28786         mkdir -p $DIR/$tdir
28787         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28788                 error "Fail to create $DIR/$tdir/dir0"
28789
28790         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28791         local dev=$(mdsdevname 2)
28792
28793         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28794                 grep ${fid} || error "NOT found agent entry for dir0"
28795
28796         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28797                 error "Fail to create $DIR/$tdir/dir1"
28798
28799         touch $DIR/$tdir/dir1/foo0 ||
28800                 error "Fail to create $DIR/$tdir/dir1/foo0"
28801         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28802         local rc=0
28803
28804         for idx in $(seq $MDSCOUNT); do
28805                 dev=$(mdsdevname $idx)
28806                 do_facet mds${idx} \
28807                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28808                         grep ${fid} && rc=$idx
28809         done
28810
28811         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28812                 error "Fail to rename foo0 to foo1"
28813         if [ $rc -eq 0 ]; then
28814                 for idx in $(seq $MDSCOUNT); do
28815                         dev=$(mdsdevname $idx)
28816                         do_facet mds${idx} \
28817                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28818                         grep ${fid} && rc=$idx
28819                 done
28820         fi
28821
28822         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28823                 error "Fail to rename foo1 to foo2"
28824         if [ $rc -eq 0 ]; then
28825                 for idx in $(seq $MDSCOUNT); do
28826                         dev=$(mdsdevname $idx)
28827                         do_facet mds${idx} \
28828                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28829                         grep ${fid} && rc=$idx
28830                 done
28831         fi
28832
28833         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28834
28835         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28836                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28837         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28838                 error "Fail to rename foo2 to foo0"
28839         unlink $DIR/$tdir/dir1/foo0 ||
28840                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28841         rm -rf $DIR/$tdir/dir0 ||
28842                 error "Fail to rm $DIR/$tdir/dir0"
28843
28844         for idx in $(seq $MDSCOUNT); do
28845                 rc=0
28846
28847                 stop mds${idx}
28848                 dev=$(mdsdevname $idx)
28849                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28850                         rc=$?
28851                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28852                         error "mount mds$idx failed"
28853                 df $MOUNT > /dev/null 2>&1
28854
28855                 # e2fsck should not return error
28856                 [ $rc -eq 0 ] ||
28857                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28858         done
28859 }
28860 run_test 804 "verify agent entry for remote entry"
28861
28862 cleanup_805() {
28863         do_facet $SINGLEMDS zfs set quota=$old $fsset
28864         unlinkmany $DIR/$tdir/f- 1000000
28865         trap 0
28866 }
28867
28868 test_805() {
28869         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28870         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28871         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28872                 skip "netfree not implemented before 0.7"
28873         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28874                 skip "Need MDS version at least 2.10.57"
28875
28876         local fsset
28877         local freekb
28878         local usedkb
28879         local old
28880         local quota
28881         local pref="osd-zfs.$FSNAME-MDT0000."
28882
28883         # limit available space on MDS dataset to meet nospace issue
28884         # quickly. then ZFS 0.7.2 can use reserved space if asked
28885         # properly (using netfree flag in osd_declare_destroy()
28886         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28887         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28888                 gawk '{print $3}')
28889         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28890         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28891         let "usedkb=usedkb-freekb"
28892         let "freekb=freekb/2"
28893         if let "freekb > 5000"; then
28894                 let "freekb=5000"
28895         fi
28896         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28897         trap cleanup_805 EXIT
28898         mkdir_on_mdt0 $DIR/$tdir
28899         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28900                 error "Can't set PFL layout"
28901         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28902         rm -rf $DIR/$tdir || error "not able to remove"
28903         do_facet $SINGLEMDS zfs set quota=$old $fsset
28904         trap 0
28905 }
28906 run_test 805 "ZFS can remove from full fs"
28907
28908 # Size-on-MDS test
28909 check_lsom_data()
28910 {
28911         local file=$1
28912         local expect=$(stat -c %s $file)
28913
28914         check_lsom_size $1 $expect
28915
28916         local blocks=$($LFS getsom -b $file)
28917         expect=$(stat -c %b $file)
28918         [[ $blocks == $expect ]] ||
28919                 error "$file expected blocks: $expect, got: $blocks"
28920 }
28921
28922 check_lsom_size()
28923 {
28924         local size
28925         local expect=$2
28926
28927         cancel_lru_locks mdc
28928
28929         size=$($LFS getsom -s $1)
28930         [[ $size == $expect ]] ||
28931                 error "$file expected size: $expect, got: $size"
28932 }
28933
28934 test_806() {
28935         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28936                 skip "Need MDS version at least 2.11.52"
28937
28938         local bs=1048576
28939
28940         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
28941
28942         disable_opencache
28943         stack_trap "restore_opencache"
28944
28945         # single-threaded write
28946         echo "Test SOM for single-threaded write"
28947         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28948                 error "write $tfile failed"
28949         check_lsom_size $DIR/$tfile $bs
28950
28951         local num=32
28952         local size=$(($num * $bs))
28953         local offset=0
28954         local i
28955
28956         echo "Test SOM for single client multi-threaded($num) write"
28957         $TRUNCATE $DIR/$tfile 0
28958         for ((i = 0; i < $num; i++)); do
28959                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28960                 local pids[$i]=$!
28961                 offset=$((offset + $bs))
28962         done
28963         for (( i=0; i < $num; i++ )); do
28964                 wait ${pids[$i]}
28965         done
28966         check_lsom_size $DIR/$tfile $size
28967
28968         $TRUNCATE $DIR/$tfile 0
28969         for ((i = 0; i < $num; i++)); do
28970                 offset=$((offset - $bs))
28971                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28972                 local pids[$i]=$!
28973         done
28974         for (( i=0; i < $num; i++ )); do
28975                 wait ${pids[$i]}
28976         done
28977         check_lsom_size $DIR/$tfile $size
28978
28979         # multi-client writes
28980         num=$(get_node_count ${CLIENTS//,/ })
28981         size=$(($num * $bs))
28982         offset=0
28983         i=0
28984
28985         echo "Test SOM for multi-client ($num) writes"
28986         $TRUNCATE $DIR/$tfile 0
28987         for client in ${CLIENTS//,/ }; do
28988                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28989                 local pids[$i]=$!
28990                 i=$((i + 1))
28991                 offset=$((offset + $bs))
28992         done
28993         for (( i=0; i < $num; i++ )); do
28994                 wait ${pids[$i]}
28995         done
28996         check_lsom_size $DIR/$tfile $offset
28997
28998         i=0
28999         $TRUNCATE $DIR/$tfile 0
29000         for client in ${CLIENTS//,/ }; do
29001                 offset=$((offset - $bs))
29002                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29003                 local pids[$i]=$!
29004                 i=$((i + 1))
29005         done
29006         for (( i=0; i < $num; i++ )); do
29007                 wait ${pids[$i]}
29008         done
29009         check_lsom_size $DIR/$tfile $size
29010
29011         # verify SOM blocks count
29012         echo "Verify SOM block count"
29013         $TRUNCATE $DIR/$tfile 0
29014         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29015                 error "failed to write file $tfile with fdatasync and fstat"
29016         check_lsom_data $DIR/$tfile
29017
29018         $TRUNCATE $DIR/$tfile 0
29019         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29020                 error "failed to write file $tfile with fdatasync"
29021         check_lsom_data $DIR/$tfile
29022
29023         $TRUNCATE $DIR/$tfile 0
29024         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29025                 error "failed to write file $tfile with sync IO"
29026         check_lsom_data $DIR/$tfile
29027
29028         # verify truncate
29029         echo "Test SOM for truncate"
29030         # use ftruncate to sync blocks on close request
29031         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29032         check_lsom_size $DIR/$tfile 16384
29033         check_lsom_data $DIR/$tfile
29034
29035         $TRUNCATE $DIR/$tfile 1234
29036         check_lsom_size $DIR/$tfile 1234
29037         # sync blocks on the MDT
29038         $MULTIOP $DIR/$tfile oc
29039         check_lsom_data $DIR/$tfile
29040 }
29041 run_test 806 "Verify Lazy Size on MDS"
29042
29043 test_807() {
29044         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29045         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29046                 skip "Need MDS version at least 2.11.52"
29047
29048         # Registration step
29049         changelog_register || error "changelog_register failed"
29050         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29051         changelog_users $SINGLEMDS | grep -q $cl_user ||
29052                 error "User $cl_user not found in changelog_users"
29053
29054         rm -rf $DIR/$tdir || error "rm $tdir failed"
29055         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29056         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29057         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29058         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29059                 error "truncate $tdir/trunc failed"
29060
29061         local bs=1048576
29062         echo "Test SOM for single-threaded write with fsync"
29063         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29064                 error "write $tfile failed"
29065         sync;sync;sync
29066
29067         # multi-client wirtes
29068         local num=$(get_node_count ${CLIENTS//,/ })
29069         local offset=0
29070         local i=0
29071
29072         echo "Test SOM for multi-client ($num) writes"
29073         touch $DIR/$tfile || error "touch $tfile failed"
29074         $TRUNCATE $DIR/$tfile 0
29075         for client in ${CLIENTS//,/ }; do
29076                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29077                 local pids[$i]=$!
29078                 i=$((i + 1))
29079                 offset=$((offset + $bs))
29080         done
29081         for (( i=0; i < $num; i++ )); do
29082                 wait ${pids[$i]}
29083         done
29084
29085         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29086         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29087         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29088         check_lsom_data $DIR/$tdir/trunc
29089         check_lsom_data $DIR/$tdir/single_dd
29090         check_lsom_data $DIR/$tfile
29091
29092         rm -rf $DIR/$tdir
29093         # Deregistration step
29094         changelog_deregister || error "changelog_deregister failed"
29095 }
29096 run_test 807 "verify LSOM syncing tool"
29097
29098 check_som_nologged()
29099 {
29100         local lines=$($LFS changelog $FSNAME-MDT0000 |
29101                 grep 'x=trusted.som' | wc -l)
29102         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29103 }
29104
29105 test_808() {
29106         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29107                 skip "Need MDS version at least 2.11.55"
29108
29109         # Registration step
29110         changelog_register || error "changelog_register failed"
29111
29112         touch $DIR/$tfile || error "touch $tfile failed"
29113         check_som_nologged
29114
29115         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29116                 error "write $tfile failed"
29117         check_som_nologged
29118
29119         $TRUNCATE $DIR/$tfile 1234
29120         check_som_nologged
29121
29122         $TRUNCATE $DIR/$tfile 1048576
29123         check_som_nologged
29124
29125         # Deregistration step
29126         changelog_deregister || error "changelog_deregister failed"
29127 }
29128 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29129
29130 check_som_nodata()
29131 {
29132         $LFS getsom $1
29133         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29134 }
29135
29136 test_809() {
29137         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29138                 skip "Need MDS version at least 2.11.56"
29139
29140         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29141                 error "failed to create DoM-only file $DIR/$tfile"
29142         touch $DIR/$tfile || error "touch $tfile failed"
29143         check_som_nodata $DIR/$tfile
29144
29145         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29146                 error "write $tfile failed"
29147         check_som_nodata $DIR/$tfile
29148
29149         $TRUNCATE $DIR/$tfile 1234
29150         check_som_nodata $DIR/$tfile
29151
29152         $TRUNCATE $DIR/$tfile 4097
29153         check_som_nodata $DIR/$file
29154 }
29155 run_test 809 "Verify no SOM xattr store for DoM-only files"
29156
29157 test_810() {
29158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29159         $GSS && skip_env "could not run with gss"
29160         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29161                 skip "OST < 2.12.58 doesn't align checksum"
29162
29163         set_checksums 1
29164         stack_trap "set_checksums $ORIG_CSUM" EXIT
29165         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29166
29167         local csum
29168         local before
29169         local after
29170         for csum in $CKSUM_TYPES; do
29171                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29172                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29173                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29174                         eval set -- $i
29175                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29176                         before=$(md5sum $DIR/$tfile)
29177                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29178                         after=$(md5sum $DIR/$tfile)
29179                         [ "$before" == "$after" ] ||
29180                                 error "$csum: $before != $after bs=$1 seek=$2"
29181                 done
29182         done
29183 }
29184 run_test 810 "partial page writes on ZFS (LU-11663)"
29185
29186 test_812a() {
29187         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29188                 skip "OST < 2.12.51 doesn't support this fail_loc"
29189
29190         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29191         # ensure ost1 is connected
29192         stat $DIR/$tfile >/dev/null || error "can't stat"
29193         wait_osc_import_state client ost1 FULL
29194         # no locks, no reqs to let the connection idle
29195         cancel_lru_locks osc
29196
29197         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29198 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29199         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29200         wait_osc_import_state client ost1 CONNECTING
29201         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29202
29203         stat $DIR/$tfile >/dev/null || error "can't stat file"
29204 }
29205 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29206
29207 test_812b() { # LU-12378
29208         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29209                 skip "OST < 2.12.51 doesn't support this fail_loc"
29210
29211         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29212         # ensure ost1 is connected
29213         stat $DIR/$tfile >/dev/null || error "can't stat"
29214         wait_osc_import_state client ost1 FULL
29215         # no locks, no reqs to let the connection idle
29216         cancel_lru_locks osc
29217
29218         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29219 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29220         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29221         wait_osc_import_state client ost1 CONNECTING
29222         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29223
29224         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29225         wait_osc_import_state client ost1 IDLE
29226 }
29227 run_test 812b "do not drop no resend request for idle connect"
29228
29229 test_812c() {
29230         local old
29231
29232         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29233
29234         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29235         $LFS getstripe $DIR/$tfile
29236         $LCTL set_param osc.*.idle_timeout=10
29237         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29238         # ensure ost1 is connected
29239         stat $DIR/$tfile >/dev/null || error "can't stat"
29240         wait_osc_import_state client ost1 FULL
29241         # no locks, no reqs to let the connection idle
29242         cancel_lru_locks osc
29243
29244 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29245         $LCTL set_param fail_loc=0x80000533
29246         sleep 15
29247         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29248 }
29249 run_test 812c "idle import vs lock enqueue race"
29250
29251 test_813() {
29252         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29253         [ -z "$file_heat_sav" ] && skip "no file heat support"
29254
29255         local readsample
29256         local writesample
29257         local readbyte
29258         local writebyte
29259         local readsample1
29260         local writesample1
29261         local readbyte1
29262         local writebyte1
29263
29264         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29265         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29266
29267         $LCTL set_param -n llite.*.file_heat=1
29268         echo "Turn on file heat"
29269         echo "Period second: $period_second, Decay percentage: $decay_pct"
29270
29271         echo "QQQQ" > $DIR/$tfile
29272         echo "QQQQ" > $DIR/$tfile
29273         echo "QQQQ" > $DIR/$tfile
29274         cat $DIR/$tfile > /dev/null
29275         cat $DIR/$tfile > /dev/null
29276         cat $DIR/$tfile > /dev/null
29277         cat $DIR/$tfile > /dev/null
29278
29279         local out=$($LFS heat_get $DIR/$tfile)
29280
29281         $LFS heat_get $DIR/$tfile
29282         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29283         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29284         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29285         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29286
29287         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29288         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29289         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29290         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29291
29292         sleep $((period_second + 3))
29293         echo "Sleep $((period_second + 3)) seconds..."
29294         # The recursion formula to calculate the heat of the file f is as
29295         # follow:
29296         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29297         # Where Hi is the heat value in the period between time points i*I and
29298         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29299         # to the weight of Ci.
29300         out=$($LFS heat_get $DIR/$tfile)
29301         $LFS heat_get $DIR/$tfile
29302         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29303         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29304         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29305         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29306
29307         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29308                 error "read sample ($readsample) is wrong"
29309         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29310                 error "write sample ($writesample) is wrong"
29311         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29312                 error "read bytes ($readbyte) is wrong"
29313         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29314                 error "write bytes ($writebyte) is wrong"
29315
29316         echo "QQQQ" > $DIR/$tfile
29317         echo "QQQQ" > $DIR/$tfile
29318         echo "QQQQ" > $DIR/$tfile
29319         cat $DIR/$tfile > /dev/null
29320         cat $DIR/$tfile > /dev/null
29321         cat $DIR/$tfile > /dev/null
29322         cat $DIR/$tfile > /dev/null
29323
29324         sleep $((period_second + 3))
29325         echo "Sleep $((period_second + 3)) seconds..."
29326
29327         out=$($LFS heat_get $DIR/$tfile)
29328         $LFS heat_get $DIR/$tfile
29329         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29330         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29331         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29332         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29333
29334         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29335                 4 * $decay_pct) / 100") -eq 1 ] ||
29336                 error "read sample ($readsample1) is wrong"
29337         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29338                 3 * $decay_pct) / 100") -eq 1 ] ||
29339                 error "write sample ($writesample1) is wrong"
29340         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29341                 20 * $decay_pct) / 100") -eq 1 ] ||
29342                 error "read bytes ($readbyte1) is wrong"
29343         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29344                 15 * $decay_pct) / 100") -eq 1 ] ||
29345                 error "write bytes ($writebyte1) is wrong"
29346
29347         echo "Turn off file heat for the file $DIR/$tfile"
29348         $LFS heat_set -o $DIR/$tfile
29349
29350         echo "QQQQ" > $DIR/$tfile
29351         echo "QQQQ" > $DIR/$tfile
29352         echo "QQQQ" > $DIR/$tfile
29353         cat $DIR/$tfile > /dev/null
29354         cat $DIR/$tfile > /dev/null
29355         cat $DIR/$tfile > /dev/null
29356         cat $DIR/$tfile > /dev/null
29357
29358         out=$($LFS heat_get $DIR/$tfile)
29359         $LFS heat_get $DIR/$tfile
29360         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29361         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29362         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29363         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29364
29365         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29366         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29367         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29368         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29369
29370         echo "Trun on file heat for the file $DIR/$tfile"
29371         $LFS heat_set -O $DIR/$tfile
29372
29373         echo "QQQQ" > $DIR/$tfile
29374         echo "QQQQ" > $DIR/$tfile
29375         echo "QQQQ" > $DIR/$tfile
29376         cat $DIR/$tfile > /dev/null
29377         cat $DIR/$tfile > /dev/null
29378         cat $DIR/$tfile > /dev/null
29379         cat $DIR/$tfile > /dev/null
29380
29381         out=$($LFS heat_get $DIR/$tfile)
29382         $LFS heat_get $DIR/$tfile
29383         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29384         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29385         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29386         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29387
29388         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29389         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29390         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29391         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29392
29393         $LFS heat_set -c $DIR/$tfile
29394         $LCTL set_param -n llite.*.file_heat=0
29395         echo "Turn off file heat support for the Lustre filesystem"
29396
29397         echo "QQQQ" > $DIR/$tfile
29398         echo "QQQQ" > $DIR/$tfile
29399         echo "QQQQ" > $DIR/$tfile
29400         cat $DIR/$tfile > /dev/null
29401         cat $DIR/$tfile > /dev/null
29402         cat $DIR/$tfile > /dev/null
29403         cat $DIR/$tfile > /dev/null
29404
29405         out=$($LFS heat_get $DIR/$tfile)
29406         $LFS heat_get $DIR/$tfile
29407         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29408         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29409         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29410         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29411
29412         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29413         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29414         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29415         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29416
29417         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29418         rm -f $DIR/$tfile
29419 }
29420 run_test 813 "File heat verfication"
29421
29422 test_814()
29423 {
29424         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29425         echo -n y >> $DIR/$tfile
29426         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29427         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29428 }
29429 run_test 814 "sparse cp works as expected (LU-12361)"
29430
29431 test_815()
29432 {
29433         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29434         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29435 }
29436 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29437
29438 test_816() {
29439         local ost1_imp=$(get_osc_import_name client ost1)
29440         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29441                          cut -d'.' -f2)
29442
29443         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29444         # ensure ost1 is connected
29445
29446         stat $DIR/$tfile >/dev/null || error "can't stat"
29447         wait_osc_import_state client ost1 FULL
29448         # no locks, no reqs to let the connection idle
29449         cancel_lru_locks osc
29450         lru_resize_disable osc
29451         local before
29452         local now
29453         before=$($LCTL get_param -n \
29454                  ldlm.namespaces.$imp_name.lru_size)
29455
29456         wait_osc_import_state client ost1 IDLE
29457         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29458         now=$($LCTL get_param -n \
29459               ldlm.namespaces.$imp_name.lru_size)
29460         [ $before == $now ] || error "lru_size changed $before != $now"
29461 }
29462 run_test 816 "do not reset lru_resize on idle reconnect"
29463
29464 cleanup_817() {
29465         umount $tmpdir
29466         exportfs -u localhost:$DIR/nfsexp
29467         rm -rf $DIR/nfsexp
29468 }
29469
29470 test_817() {
29471         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29472
29473         mkdir -p $DIR/nfsexp
29474         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29475                 error "failed to export nfs"
29476
29477         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29478         stack_trap cleanup_817 EXIT
29479
29480         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29481                 error "failed to mount nfs to $tmpdir"
29482
29483         cp /bin/true $tmpdir
29484         $DIR/nfsexp/true || error "failed to execute 'true' command"
29485 }
29486 run_test 817 "nfsd won't cache write lock for exec file"
29487
29488 test_818() {
29489         test_mkdir -i0 -c1 $DIR/$tdir
29490         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29491         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29492         stop $SINGLEMDS
29493
29494         # restore osp-syn threads
29495         stack_trap "fail $SINGLEMDS"
29496
29497         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29498         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29499         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29500                 error "start $SINGLEMDS failed"
29501         rm -rf $DIR/$tdir
29502
29503         local testid=$(echo $TESTNAME | tr '_' ' ')
29504
29505         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29506                 grep "run LFSCK" || error "run LFSCK is not suggested"
29507 }
29508 run_test 818 "unlink with failed llog"
29509
29510 test_819a() {
29511         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29512         cancel_lru_locks osc
29513         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29514         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29515         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29516         rm -f $TDIR/$tfile
29517 }
29518 run_test 819a "too big niobuf in read"
29519
29520 test_819b() {
29521         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29522         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29523         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29524         cancel_lru_locks osc
29525         sleep 1
29526         rm -f $TDIR/$tfile
29527 }
29528 run_test 819b "too big niobuf in write"
29529
29530
29531 function test_820_start_ost() {
29532         sleep 5
29533
29534         for num in $(seq $OSTCOUNT); do
29535                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29536         done
29537 }
29538
29539 test_820() {
29540         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29541
29542         mkdir $DIR/$tdir
29543         umount_client $MOUNT || error "umount failed"
29544         for num in $(seq $OSTCOUNT); do
29545                 stop ost$num
29546         done
29547
29548         # mount client with no active OSTs
29549         # so that the client can't initialize max LOV EA size
29550         # from OSC notifications
29551         mount_client $MOUNT || error "mount failed"
29552         # delay OST starting to keep this 0 max EA size for a while
29553         test_820_start_ost &
29554
29555         # create a directory on MDS2
29556         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29557                 error "Failed to create directory"
29558         # open intent should update default EA size
29559         # see mdc_update_max_ea_from_body()
29560         # notice this is the very first RPC to MDS2
29561         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29562         ret=$?
29563         echo $out
29564         # With SSK, this situation can lead to -EPERM being returned.
29565         # In that case, simply retry.
29566         if [ $ret -ne 0 ] && $SHARED_KEY; then
29567                 if echo "$out" | grep -q "not permitted"; then
29568                         cp /etc/services $DIR/$tdir/mds2
29569                         ret=$?
29570                 fi
29571         fi
29572         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29573 }
29574 run_test 820 "update max EA from open intent"
29575
29576 test_823() {
29577         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29578         local OST_MAX_PRECREATE=20000
29579
29580         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29581                 skip "Need MDS version at least 2.14.56"
29582
29583         save_lustre_params mds1 \
29584                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29585         do_facet $SINGLEMDS "$LCTL set_param -n \
29586                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29587         do_facet $SINGLEMDS "$LCTL set_param -n \
29588                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29589
29590         stack_trap "restore_lustre_params < $p; rm $p"
29591
29592         do_facet $SINGLEMDS "$LCTL set_param -n \
29593                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29594
29595         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29596                       osp.$FSNAME-OST0000*MDT0000.create_count")
29597         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29598                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29599         local expect_count=$(((($max/2)/256) * 256))
29600
29601         log "setting create_count to 100200:"
29602         log " -result- count: $count with max: $max, expecting: $expect_count"
29603
29604         [[ $count -eq expect_count ]] ||
29605                 error "Create count not set to max precreate."
29606 }
29607 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29608
29609 test_831() {
29610         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29611                 skip "Need MDS version 2.14.56"
29612
29613         local sync_changes=$(do_facet $SINGLEMDS \
29614                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29615
29616         [ "$sync_changes" -gt 100 ] &&
29617                 skip "Sync changes $sync_changes > 100 already"
29618
29619         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29620
29621         $LFS mkdir -i 0 $DIR/$tdir
29622         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29623
29624         save_lustre_params mds1 \
29625                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29626         save_lustre_params mds1 \
29627                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29628
29629         do_facet mds1 "$LCTL set_param -n \
29630                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29631                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29632         stack_trap "restore_lustre_params < $p" EXIT
29633
29634         createmany -o $DIR/$tdir/f- 1000
29635         unlinkmany $DIR/$tdir/f- 1000 &
29636         local UNLINK_PID=$!
29637
29638         while sleep 1; do
29639                 sync_changes=$(do_facet mds1 \
29640                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29641                 # the check in the code is racy, fail the test
29642                 # if the value above the limit by 10.
29643                 [ $sync_changes -gt 110 ] && {
29644                         kill -2 $UNLINK_PID
29645                         wait
29646                         error "osp changes throttling failed, $sync_changes>110"
29647                 }
29648                 kill -0 $UNLINK_PID 2> /dev/null || break
29649         done
29650         wait
29651 }
29652 run_test 831 "throttling unlink/setattr queuing on OSP"
29653
29654 test_832() {
29655         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29656         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29657                 skip "Need MDS version 2.15.52+"
29658         is_rmentry_supported || skip "rm_entry not supported"
29659
29660         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29661         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29662         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29663                 error "mkdir remote_dir failed"
29664         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29665                 error "mkdir striped_dir failed"
29666         touch $DIR/$tdir/file || error "touch file failed"
29667         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29668         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29669 }
29670 run_test 832 "lfs rm_entry"
29671
29672 #
29673 # tests that do cleanup/setup should be run at the end
29674 #
29675
29676 test_900() {
29677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29678         local ls
29679
29680         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29681         $LCTL set_param fail_loc=0x903
29682
29683         cancel_lru_locks MGC
29684
29685         FAIL_ON_ERROR=true cleanup
29686         FAIL_ON_ERROR=true setup
29687 }
29688 run_test 900 "umount should not race with any mgc requeue thread"
29689
29690 # LUS-6253/LU-11185
29691 test_901() {
29692         local old
29693         local count
29694         local oldc
29695         local newc
29696         local olds
29697         local news
29698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29699
29700         # some get_param have a bug to handle dot in param name
29701         cancel_lru_locks MGC
29702         old=$(mount -t lustre | wc -l)
29703         # 1 config+sptlrpc
29704         # 2 params
29705         # 3 nodemap
29706         # 4 IR
29707         old=$((old * 4))
29708         oldc=0
29709         count=0
29710         while [ $old -ne $oldc ]; do
29711                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29712                 sleep 1
29713                 ((count++))
29714                 if [ $count -ge $TIMEOUT ]; then
29715                         error "too large timeout"
29716                 fi
29717         done
29718         umount_client $MOUNT || error "umount failed"
29719         mount_client $MOUNT || error "mount failed"
29720         cancel_lru_locks MGC
29721         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29722
29723         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29724
29725         return 0
29726 }
29727 run_test 901 "don't leak a mgc lock on client umount"
29728
29729 # LU-13377
29730 test_902() {
29731         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29732                 skip "client does not have LU-13377 fix"
29733         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29734         $LCTL set_param fail_loc=0x1415
29735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29736         cancel_lru_locks osc
29737         rm -f $DIR/$tfile
29738 }
29739 run_test 902 "test short write doesn't hang lustre"
29740
29741 # LU-14711
29742 test_903() {
29743         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29744         echo "blah" > $DIR/${tfile}-2
29745         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29746         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29747         $LCTL set_param fail_loc=0x417 fail_val=20
29748
29749         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29750         sleep 1 # To start the destroy
29751         wait_destroy_complete 150 || error "Destroy taking too long"
29752         cat $DIR/$tfile > /dev/null || error "Evicted"
29753 }
29754 run_test 903 "Test long page discard does not cause evictions"
29755
29756 test_904() {
29757         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29758         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29759                 grep -q project || skip "skip project quota not supported"
29760
29761         local testfile="$DIR/$tdir/$tfile"
29762         local xattr="trusted.projid"
29763         local projid
29764         local mdts=$(comma_list $(mdts_nodes))
29765         local saved=$(do_facet mds1 $LCTL get_param -n \
29766                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29767
29768         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29769         stack_trap "do_nodes $mdts $LCTL set_param \
29770                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29771
29772         mkdir -p $DIR/$tdir
29773         touch $testfile
29774         #hide projid xattr on server
29775         $LFS project -p 1 $testfile ||
29776                 error "set $testfile project id failed"
29777         getfattr -m - $testfile | grep $xattr &&
29778                 error "do not show trusted.projid when disabled on server"
29779         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29780         #should be hidden when projid is 0
29781         $LFS project -p 0 $testfile ||
29782                 error "set $testfile project id failed"
29783         getfattr -m - $testfile | grep $xattr &&
29784                 error "do not show trusted.projid with project ID 0"
29785
29786         #still can getxattr explicitly
29787         projid=$(getfattr -n $xattr $testfile |
29788                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29789         [ $projid == "0" ] ||
29790                 error "projid expected 0 not $projid"
29791
29792         #set the projid via setxattr
29793         setfattr -n $xattr -v "1000" $testfile ||
29794                 error "setattr failed with $?"
29795         projid=($($LFS project $testfile))
29796         [ ${projid[0]} == "1000" ] ||
29797                 error "projid expected 1000 not $projid"
29798
29799         #check the new projid via getxattr
29800         $LFS project -p 1001 $testfile ||
29801                 error "set $testfile project id failed"
29802         getfattr -m - $testfile | grep $xattr ||
29803                 error "should show trusted.projid when project ID != 0"
29804         projid=$(getfattr -n $xattr $testfile |
29805                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29806         [ $projid == "1001" ] ||
29807                 error "projid expected 1001 not $projid"
29808
29809         #try to set invalid projid
29810         setfattr -n $xattr -v "4294967295" $testfile &&
29811                 error "set invalid projid should fail"
29812
29813         #remove the xattr means setting projid to 0
29814         setfattr -x $xattr $testfile ||
29815                 error "setfattr failed with $?"
29816         projid=($($LFS project $testfile))
29817         [ ${projid[0]} == "0" ] ||
29818                 error "projid expected 0 not $projid"
29819
29820         #should be hidden when parent has inherit flag and same projid
29821         $LFS project -srp 1002 $DIR/$tdir ||
29822                 error "set $tdir project id failed"
29823         getfattr -m - $testfile | grep $xattr &&
29824                 error "do not show trusted.projid with inherit flag"
29825
29826         #still can getxattr explicitly
29827         projid=$(getfattr -n $xattr $testfile |
29828                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29829         [ $projid == "1002" ] ||
29830                 error "projid expected 1002 not $projid"
29831 }
29832 run_test 904 "virtual project ID xattr"
29833
29834 # LU-8582
29835 test_905() {
29836         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29837                 skip "lustre < 2.8.54 does not support ladvise"
29838
29839         remote_ost_nodsh && skip "remote OST with nodsh"
29840         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29841
29842         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29843
29844         #define OBD_FAIL_OST_OPCODE 0x253
29845         # OST_LADVISE = 21
29846         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29847         $LFS ladvise -a willread $DIR/$tfile &&
29848                 error "unexpected success of ladvise with fault injection"
29849         $LFS ladvise -a willread $DIR/$tfile |&
29850                 grep -q "Operation not supported"
29851         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29852 }
29853 run_test 905 "bad or new opcode should not stuck client"
29854
29855 test_906() {
29856         grep -q io_uring_setup /proc/kallsyms ||
29857                 skip "Client OS does not support io_uring I/O engine"
29858         io_uring_probe || skip "kernel does not support io_uring fully"
29859         which fio || skip_env "no fio installed"
29860         fio --enghelp | grep -q io_uring ||
29861                 skip_env "fio does not support io_uring I/O engine"
29862
29863         local file=$DIR/$tfile
29864         local ioengine="io_uring"
29865         local numjobs=2
29866         local size=50M
29867
29868         fio --name=seqwrite --ioengine=$ioengine        \
29869                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29870                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29871                 error "fio seqwrite $file failed"
29872
29873         fio --name=seqread --ioengine=$ioengine \
29874                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29875                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29876                 error "fio seqread $file failed"
29877
29878         rm -f $file || error "rm -f $file failed"
29879 }
29880 run_test 906 "Simple test for io_uring I/O engine via fio"
29881
29882 complete $SECONDS
29883 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29884 check_and_cleanup_lustre
29885 if [ "$I_MOUNTED" != "yes" ]; then
29886         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29887 fi
29888 exit_status