Whamcloud - gitweb
LU-16027 tests: sanity:test_66: specify blocksize explicitly
[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-14541 277
44 always_except LU-9054  312
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 ACL tests on RHEL8 and SLES15 until tests changed to use other users
67 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
68         always_except LU-15259 103a 125 154a
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
73
74 if [ "$mds1_FSTYPE" = "zfs" ]; then
75         #                                               13    (min)"
76         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [ "$ost1_FSTYPE" = "zfs" ]; then
80         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         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
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967         local mdts=$(comma_list $(mdts_nodes))
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Validate existing append_* params and ensure restore
2983         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2984         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2985         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2986
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2990
2991         $LFS setstripe $stripe_opt $DIR/$tdir
2992
2993         echo 1 > $DIR/$tdir/${tfile}.1
2994         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         pool_add $TESTNAME || error "pool creation failed"
3076         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078
3079         echo 1 >> $DIR/$tdir/${tfile}.10_append
3080
3081         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3082         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3083
3084         # Check that count is still correct
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.11_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(11) stripe count $count, should be $appendcount for append"
3090
3091         # Disable O_APPEND stripe count, verify pool works separately
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3093
3094         echo 1 >> $DIR/$tdir/${tfile}.12_append
3095
3096         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3097         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3098
3099         # Remove pool setting, verify it's not applied
3100         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.13_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3105         [ "$pool" = "" ] || error "(13) pool found: $pool"
3106 }
3107 run_test 27M "test O_APPEND striping"
3108
3109 test_27N() {
3110         combined_mgs_mds && skip "needs separate MGS/MDT"
3111
3112         pool_add $TESTNAME || error "pool_add failed"
3113         do_facet mgs "$LCTL pool_list $FSNAME" |
3114                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3115                 error "lctl pool_list on MGS failed"
3116 }
3117 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3118
3119 clean_foreign_symlink() {
3120         trap 0
3121         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3122         for i in $DIR/$tdir/* ; do
3123                 $LFS unlink_foreign $i || true
3124         done
3125 }
3126
3127 test_27O() {
3128         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3129                 skip "Need MDS version newer than 2.12.51"
3130
3131         test_mkdir $DIR/$tdir
3132         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3133         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3134
3135         trap clean_foreign_symlink EXIT
3136
3137         # enable foreign_symlink behaviour
3138         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3139
3140         # foreign symlink LOV format is a partial path by default
3141
3142         # create foreign file (lfs + API)
3143         $LFS setstripe --foreign=symlink --flags 0xda05 \
3144                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3145                 error "$DIR/$tdir/${tfile}: create failed"
3146
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_magic:.*0x0BD70BD0" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_flags:.*0x0000DA05" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3155         $LFS getstripe $DIR/$tdir/${tfile} |
3156                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3158
3159         # modify striping should fail
3160         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: setstripe should fail"
3162
3163         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3164         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3165         cat /etc/passwd > $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: write should fail"
3167
3168         # rename should succeed
3169         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3170                 error "$DIR/$tdir/$tfile: rename has failed"
3171
3172         #remove foreign_symlink file should fail
3173         rm $DIR/$tdir/${tfile}.new &&
3174                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3175
3176         #test fake symlink
3177         mkdir /tmp/${uuid1} ||
3178                 error "/tmp/${uuid1}: mkdir has failed"
3179         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3180                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3181         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3182         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3184         #read should succeed now
3185         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3186                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3187         #write should succeed now
3188         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3190         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3192         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3194
3195         #check that getstripe still works
3196         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3198
3199         # chmod should still succeed
3200         chmod 644 $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3202
3203         # chown should still succeed
3204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3206
3207         # rename should still succeed
3208         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3209                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3210
3211         #remove foreign_symlink file should still fail
3212         rm $DIR/$tdir/${tfile} &&
3213                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3214
3215         #use special ioctl() to unlink foreign_symlink file
3216         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3218
3219 }
3220 run_test 27O "basic ops on foreign file of symlink type"
3221
3222 test_27P() {
3223         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3224                 skip "Need MDS version newer than 2.12.49"
3225
3226         test_mkdir $DIR/$tdir
3227         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3228         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3229
3230         trap clean_foreign_symlink EXIT
3231
3232         # enable foreign_symlink behaviour
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3234
3235         # foreign symlink LMV format is a partial path by default
3236
3237         # create foreign dir (lfs + API)
3238         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3239                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3240                 error "$DIR/$tdir/${tdir}: create failed"
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3243
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_magic:.*0x0CD50CD0" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3249         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3250                 grep "lfm_flags:.*0x0000DA05" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3252         $LFS getdirstripe $DIR/$tdir/${tdir} |
3253                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3255
3256         # file create in dir should fail
3257         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3258         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3259
3260         # rename should succeed
3261         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3262                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3263
3264         #remove foreign_symlink dir should fail
3265         rmdir $DIR/$tdir/${tdir}.new &&
3266                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3267
3268         #test fake symlink
3269         mkdir -p /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3271         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3272                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3274         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3276         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3277                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3278
3279         #check that getstripe fails now that foreign_symlink enabled
3280         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3282
3283         # file create in dir should work now
3284         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3286         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3287                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3288         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3289                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3290
3291         # chmod should still succeed
3292         chmod 755 $DIR/$tdir/${tdir}.new ||
3293                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3294
3295         # chown should still succeed
3296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3298
3299         # rename should still succeed
3300         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3301                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should still fail
3304         rmdir $DIR/$tdir/${tdir} &&
3305                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3306
3307         #use special ioctl() to unlink foreign_symlink file
3308         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3309                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3310
3311         #created file should still exist
3312         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3314         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3315                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3316 }
3317 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3318
3319 test_27Q() {
3320         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3321         stack_trap "rm -f $TMP/$tfile*"
3322
3323         test_mkdir $DIR/$tdir-1
3324         test_mkdir $DIR/$tdir-2
3325
3326         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3327         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3328
3329         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3330         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3333         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3334
3335         # Create some bad symlinks and ensure that we don't loop
3336         # forever or something. These should return ELOOP (40) and
3337         # ENOENT (2) but I don't want to test for that because there's
3338         # always some weirdo architecture that needs to ruin
3339         # everything by defining these error numbers differently.
3340
3341         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3342         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3343
3344         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3345         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3346
3347         return 0
3348 }
3349 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3350
3351 test_27R() {
3352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3353                 skip "need MDS 2.14.55 or later"
3354         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3355
3356         local testdir="$DIR/$tdir"
3357         test_mkdir -p $testdir
3358         stack_trap "rm -rf $testdir"
3359         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3360
3361         local f1="$testdir/f1"
3362         touch $f1 || error "failed to touch $f1"
3363         local count=$($LFS getstripe -c $f1)
3364         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3365
3366         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3367         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3368
3369         local maxcount=$(($OSTCOUNT - 1))
3370         local mdts=$(comma_list $(mdts_nodes))
3371         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3372         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3373
3374         local f2="$testdir/f2"
3375         touch $f2 || error "failed to touch $f2"
3376         local count=$($LFS getstripe -c $f2)
3377         (( $count == $maxcount )) || error "wrong stripe count"
3378 }
3379 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3380
3381 test_27T() {
3382         [ $(facet_host client) == $(facet_host ost1) ] &&
3383                 skip "need ost1 and client on different nodes"
3384
3385 #define OBD_FAIL_OSC_NO_GRANT            0x411
3386         $LCTL set_param fail_loc=0x20000411 fail_val=1
3387 #define OBD_FAIL_OST_ENOSPC              0x215
3388         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3389         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3390         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3391                 error "multiop failed"
3392 }
3393 run_test 27T "no eio on close on partial write due to enosp"
3394
3395 test_27U() {
3396         local dir=$DIR/$tdir
3397         local file=$dir/$tfile
3398         local append_pool=${TESTNAME}-append
3399         local normal_pool=${TESTNAME}-normal
3400         local pool
3401         local stripe_count
3402         local stripe_count2
3403         local mdts=$(comma_list $(mdts_nodes))
3404
3405         # FIMXE
3406         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3407         #       skip "Need MDS version at least 2.15.42"
3408
3409         # Validate existing append_* params and ensure restore
3410         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3411         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3412         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3413
3414         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3415         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3416         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3417
3418         pool_add $append_pool || error "pool creation failed"
3419         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3420
3421         pool_add $normal_pool || error "pool creation failed"
3422         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3423
3424         test_mkdir $dir
3425         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3426
3427         echo XXX >> $file.1
3428         $LFS getstripe $file.1
3429
3430         pool=$($LFS getstripe -p $file.1)
3431         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3432
3433         stripe_count2=$($LFS getstripe -c $file.1)
3434         ((stripe_count2 == stripe_count)) ||
3435                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3436
3437         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3438
3439         echo XXX >> $file.2
3440         $LFS getstripe $file.2
3441
3442         pool=$($LFS getstripe -p $file.2)
3443         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3444
3445         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3446
3447         echo XXX >> $file.3
3448         $LFS getstripe $file.3
3449
3450         stripe_count2=$($LFS getstripe -c $file.3)
3451         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3452 }
3453 run_test 27U "append pool and stripe count work with composite default layout"
3454
3455 # createtest also checks that device nodes are created and
3456 # then visible correctly (#2091)
3457 test_28() { # bug 2091
3458         test_mkdir $DIR/d28
3459         $CREATETEST $DIR/d28/ct || error "createtest failed"
3460 }
3461 run_test 28 "create/mknod/mkdir with bad file types ============"
3462
3463 test_29() {
3464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3465
3466         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3467                 disable_opencache
3468                 stack_trap "restore_opencache"
3469         }
3470
3471         sync; sleep 1; sync # flush out any dirty pages from previous tests
3472         cancel_lru_locks
3473         test_mkdir $DIR/d29
3474         touch $DIR/d29/foo
3475         log 'first d29'
3476         ls -l $DIR/d29
3477
3478         declare -i LOCKCOUNTORIG=0
3479         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3480                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3481         done
3482         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3483
3484         declare -i LOCKUNUSEDCOUNTORIG=0
3485         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3486                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3487         done
3488
3489         log 'second d29'
3490         ls -l $DIR/d29
3491         log 'done'
3492
3493         declare -i LOCKCOUNTCURRENT=0
3494         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3495                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3496         done
3497
3498         declare -i LOCKUNUSEDCOUNTCURRENT=0
3499         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3500                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3501         done
3502
3503         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3504                 $LCTL set_param -n ldlm.dump_namespaces ""
3505                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 2
3509         fi
3510         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3511                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3512                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3513                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3514                 return 3
3515         fi
3516 }
3517 run_test 29 "IT_GETATTR regression  ============================"
3518
3519 test_30a() { # was test_30
3520         cp $(which ls) $DIR || cp /bin/ls $DIR
3521         $DIR/ls / || error "Can't execute binary from lustre"
3522         rm $DIR/ls
3523 }
3524 run_test 30a "execute binary from Lustre (execve) =============="
3525
3526 test_30b() {
3527         cp `which ls` $DIR || cp /bin/ls $DIR
3528         chmod go+rx $DIR/ls
3529         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3530         rm $DIR/ls
3531 }
3532 run_test 30b "execute binary from Lustre as non-root ==========="
3533
3534 test_30c() { # b=22376
3535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3536
3537         cp $(which ls) $DIR || cp /bin/ls $DIR
3538         chmod a-rw $DIR/ls
3539         cancel_lru_locks mdc
3540         cancel_lru_locks osc
3541         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3542         rm -f $DIR/ls
3543 }
3544 run_test 30c "execute binary from Lustre without read perms ===="
3545
3546 test_30d() {
3547         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3548
3549         for i in {1..10}; do
3550                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3551                 local PID=$!
3552                 sleep 1
3553                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3554                 wait $PID || error "executing dd from Lustre failed"
3555                 rm -f $DIR/$tfile
3556         done
3557
3558         rm -f $DIR/dd
3559 }
3560 run_test 30d "execute binary from Lustre while clear locks"
3561
3562 test_31a() {
3563         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3564         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3565 }
3566 run_test 31a "open-unlink file =================================="
3567
3568 test_31b() {
3569         touch $DIR/f31 || error "touch $DIR/f31 failed"
3570         ln $DIR/f31 $DIR/f31b || error "ln failed"
3571         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3572         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3573 }
3574 run_test 31b "unlink file with multiple links while open ======="
3575
3576 test_31c() {
3577         touch $DIR/f31 || error "touch $DIR/f31 failed"
3578         ln $DIR/f31 $DIR/f31c || error "ln failed"
3579         multiop_bg_pause $DIR/f31 O_uc ||
3580                 error "multiop_bg_pause for $DIR/f31 failed"
3581         MULTIPID=$!
3582         $MULTIOP $DIR/f31c Ouc
3583         kill -USR1 $MULTIPID
3584         wait $MULTIPID
3585 }
3586 run_test 31c "open-unlink file with multiple links ============="
3587
3588 test_31d() {
3589         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3590         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3591 }
3592 run_test 31d "remove of open directory ========================="
3593
3594 test_31e() { # bug 2904
3595         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3596 }
3597 run_test 31e "remove of open non-empty directory ==============="
3598
3599 test_31f() { # bug 4554
3600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3601
3602         set -vx
3603         test_mkdir $DIR/d31f
3604         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3605         cp /etc/hosts $DIR/d31f
3606         ls -l $DIR/d31f
3607         $LFS getstripe $DIR/d31f/hosts
3608         multiop_bg_pause $DIR/d31f D_c || return 1
3609         MULTIPID=$!
3610
3611         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3612         test_mkdir $DIR/d31f
3613         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3614         cp /etc/hosts $DIR/d31f
3615         ls -l $DIR/d31f
3616         $LFS getstripe $DIR/d31f/hosts
3617         multiop_bg_pause $DIR/d31f D_c || return 1
3618         MULTIPID2=$!
3619
3620         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3621         wait $MULTIPID || error "first opendir $MULTIPID failed"
3622
3623         sleep 6
3624
3625         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3626         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3627         set +vx
3628 }
3629 run_test 31f "remove of open directory with open-unlink file ==="
3630
3631 test_31g() {
3632         echo "-- cross directory link --"
3633         test_mkdir -c1 $DIR/${tdir}ga
3634         test_mkdir -c1 $DIR/${tdir}gb
3635         touch $DIR/${tdir}ga/f
3636         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3637         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3638         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3639         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3640         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3641 }
3642 run_test 31g "cross directory link==============="
3643
3644 test_31h() {
3645         echo "-- cross directory link --"
3646         test_mkdir -c1 $DIR/${tdir}
3647         test_mkdir -c1 $DIR/${tdir}/dir
3648         touch $DIR/${tdir}/f
3649         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3650         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3651         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3652         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3653         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3654 }
3655 run_test 31h "cross directory link under child==============="
3656
3657 test_31i() {
3658         echo "-- cross directory link --"
3659         test_mkdir -c1 $DIR/$tdir
3660         test_mkdir -c1 $DIR/$tdir/dir
3661         touch $DIR/$tdir/dir/f
3662         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3663         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3664         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3665         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3666         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3667 }
3668 run_test 31i "cross directory link under parent==============="
3669
3670 test_31j() {
3671         test_mkdir -c1 -p $DIR/$tdir
3672         test_mkdir -c1 -p $DIR/$tdir/dir1
3673         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3674         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3675         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3676         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3677         return 0
3678 }
3679 run_test 31j "link for directory==============="
3680
3681 test_31k() {
3682         test_mkdir -c1 -p $DIR/$tdir
3683         touch $DIR/$tdir/s
3684         touch $DIR/$tdir/exist
3685         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3686         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3687         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3688         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3689         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3690         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3691         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3692         return 0
3693 }
3694 run_test 31k "link to file: the same, non-existing, dir==============="
3695
3696 test_31m() {
3697         mkdir $DIR/d31m
3698         touch $DIR/d31m/s
3699         mkdir $DIR/d31m2
3700         touch $DIR/d31m2/exist
3701         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3702         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3703         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3704         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3705         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3706         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3707         return 0
3708 }
3709 run_test 31m "link to file: the same, non-existing, dir==============="
3710
3711 test_31n() {
3712         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3713         nlink=$(stat --format=%h $DIR/$tfile)
3714         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3715         local fd=$(free_fd)
3716         local cmd="exec $fd<$DIR/$tfile"
3717         eval $cmd
3718         cmd="exec $fd<&-"
3719         trap "eval $cmd" EXIT
3720         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3721         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3722         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3723         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3724         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3725         eval $cmd
3726 }
3727 run_test 31n "check link count of unlinked file"
3728
3729 link_one() {
3730         local tempfile=$(mktemp $1_XXXXXX)
3731         mlink $tempfile $1 2> /dev/null &&
3732                 echo "$BASHPID: link $tempfile to $1 succeeded"
3733         munlink $tempfile
3734 }
3735
3736 test_31o() { # LU-2901
3737         test_mkdir $DIR/$tdir
3738         for LOOP in $(seq 100); do
3739                 rm -f $DIR/$tdir/$tfile*
3740                 for THREAD in $(seq 8); do
3741                         link_one $DIR/$tdir/$tfile.$LOOP &
3742                 done
3743                 wait
3744                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3745                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3746                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3747                         break || true
3748         done
3749 }
3750 run_test 31o "duplicate hard links with same filename"
3751
3752 test_31p() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754
3755         test_mkdir $DIR/$tdir
3756         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3757         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3758
3759         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3760                 error "open unlink test1 failed"
3761         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3762                 error "open unlink test2 failed"
3763
3764         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3765                 error "test1 still exists"
3766         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3767                 error "test2 still exists"
3768 }
3769 run_test 31p "remove of open striped directory"
3770
3771 test_31q() {
3772         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3773
3774         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3775         index=$($LFS getdirstripe -i $DIR/$tdir)
3776         [ $index -eq 3 ] || error "first stripe index $index != 3"
3777         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3778         [ $index -eq 1 ] || error "second stripe index $index != 1"
3779
3780         # when "-c <stripe_count>" is set, the number of MDTs specified after
3781         # "-i" should equal to the stripe count
3782         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3783 }
3784 run_test 31q "create striped directory on specific MDTs"
3785
3786 #LU-14949
3787 test_31r() {
3788         touch $DIR/$tfile.target
3789         touch $DIR/$tfile.source
3790
3791         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3792         $LCTL set_param fail_loc=0x1419 fail_val=3
3793         cat $DIR/$tfile.target &
3794         CATPID=$!
3795
3796         # Guarantee open is waiting before we get here
3797         sleep 1
3798         mv $DIR/$tfile.source $DIR/$tfile.target
3799
3800         wait $CATPID
3801         RC=$?
3802         if [[ $RC -ne 0 ]]; then
3803                 error "open with cat failed, rc=$RC"
3804         fi
3805 }
3806 run_test 31r "open-rename(replace) race"
3807
3808 cleanup_test32_mount() {
3809         local rc=0
3810         trap 0
3811         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3812         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3813         losetup -d $loopdev || true
3814         rm -rf $DIR/$tdir
3815         return $rc
3816 }
3817
3818 test_32a() {
3819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3820
3821         echo "== more mountpoints and symlinks ================="
3822         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3823         trap cleanup_test32_mount EXIT
3824         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3825         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3826                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3827         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3828                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3829         cleanup_test32_mount
3830 }
3831 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3832
3833 test_32b() {
3834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3835
3836         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3837         trap cleanup_test32_mount EXIT
3838         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3839         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3840                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3841         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3842                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3843         cleanup_test32_mount
3844 }
3845 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3846
3847 test_32c() {
3848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3849
3850         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3851         trap cleanup_test32_mount EXIT
3852         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3853         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3854                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3855         test_mkdir -p $DIR/$tdir/d2/test_dir
3856         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3857                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3858         cleanup_test32_mount
3859 }
3860 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3861
3862 test_32d() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         test_mkdir -p $DIR/$tdir/d2/test_dir
3871         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3872                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3873         cleanup_test32_mount
3874 }
3875 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3876
3877 test_32e() {
3878         rm -fr $DIR/$tdir
3879         test_mkdir -p $DIR/$tdir/tmp
3880         local tmp_dir=$DIR/$tdir/tmp
3881         ln -s $DIR/$tdir $tmp_dir/symlink11
3882         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3883         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3884         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3885 }
3886 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3887
3888 test_32f() {
3889         rm -fr $DIR/$tdir
3890         test_mkdir -p $DIR/$tdir/tmp
3891         local tmp_dir=$DIR/$tdir/tmp
3892         ln -s $DIR/$tdir $tmp_dir/symlink11
3893         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3894         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3895         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3896 }
3897 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3898
3899 test_32g() {
3900         local tmp_dir=$DIR/$tdir/tmp
3901         test_mkdir -p $tmp_dir
3902         test_mkdir $DIR/${tdir}2
3903         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3904         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3905         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3906         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3907         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3908         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3909 }
3910 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3911
3912 test_32h() {
3913         rm -fr $DIR/$tdir $DIR/${tdir}2
3914         tmp_dir=$DIR/$tdir/tmp
3915         test_mkdir -p $tmp_dir
3916         test_mkdir $DIR/${tdir}2
3917         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3918         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3919         ls $tmp_dir/symlink12 || error "listing symlink12"
3920         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3921 }
3922 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3923
3924 test_32i() {
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         touch $DIR/$tdir/test_file
3933         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3934                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3935         cleanup_test32_mount
3936 }
3937 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3938
3939 test_32j() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3946                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3947         touch $DIR/$tdir/test_file
3948         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3949                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3950         cleanup_test32_mount
3951 }
3952 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3953
3954 test_32k() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         test_mkdir -p $DIR/$tdir/d2
3963         touch $DIR/$tdir/d2/test_file || error "touch failed"
3964         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3965                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3966         cleanup_test32_mount
3967 }
3968 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3969
3970 test_32l() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         rm -fr $DIR/$tdir
3974         trap cleanup_test32_mount EXIT
3975         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3976         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3977                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3978         test_mkdir -p $DIR/$tdir/d2
3979         touch $DIR/$tdir/d2/test_file || error "touch failed"
3980         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3981                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3982         cleanup_test32_mount
3983 }
3984 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3985
3986 test_32m() {
3987         rm -fr $DIR/d32m
3988         test_mkdir -p $DIR/d32m/tmp
3989         TMP_DIR=$DIR/d32m/tmp
3990         ln -s $DIR $TMP_DIR/symlink11
3991         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3992         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3993                 error "symlink11 not a link"
3994         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3995                 error "symlink01 not a link"
3996 }
3997 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3998
3999 test_32n() {
4000         rm -fr $DIR/d32n
4001         test_mkdir -p $DIR/d32n/tmp
4002         TMP_DIR=$DIR/d32n/tmp
4003         ln -s $DIR $TMP_DIR/symlink11
4004         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4005         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4006         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4007 }
4008 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4009
4010 test_32o() {
4011         touch $DIR/$tfile
4012         test_mkdir -p $DIR/d32o/tmp
4013         TMP_DIR=$DIR/d32o/tmp
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4016         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4017                 error "symlink12 not a link"
4018         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4019         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4020                 error "$DIR/d32o/tmp/symlink12 not file type"
4021         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4022                 error "$DIR/d32o/symlink02 not file type"
4023 }
4024 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32p() {
4027         log 32p_1
4028         rm -fr $DIR/d32p
4029         log 32p_2
4030         rm -f $DIR/$tfile
4031         log 32p_3
4032         touch $DIR/$tfile
4033         log 32p_4
4034         test_mkdir -p $DIR/d32p/tmp
4035         log 32p_5
4036         TMP_DIR=$DIR/d32p/tmp
4037         log 32p_6
4038         ln -s $DIR/$tfile $TMP_DIR/symlink12
4039         log 32p_7
4040         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4041         log 32p_8
4042         cat $DIR/d32p/tmp/symlink12 ||
4043                 error "Can't open $DIR/d32p/tmp/symlink12"
4044         log 32p_9
4045         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4046         log 32p_10
4047 }
4048 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4049
4050 test_32q() {
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4054         trap cleanup_test32_mount EXIT
4055         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4056         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4057         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4058                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4059         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4060         cleanup_test32_mount
4061 }
4062 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4063
4064 test_32r() {
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066
4067         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4068         trap cleanup_test32_mount EXIT
4069         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4070         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4071         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4072                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4073         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4074         cleanup_test32_mount
4075 }
4076 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4077
4078 test_33aa() {
4079         rm -f $DIR/$tfile
4080         touch $DIR/$tfile
4081         chmod 444 $DIR/$tfile
4082         chown $RUNAS_ID $DIR/$tfile
4083         log 33_1
4084         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4085         log 33_2
4086 }
4087 run_test 33aa "write file with mode 444 (should return error)"
4088
4089 test_33a() {
4090         rm -fr $DIR/$tdir
4091         test_mkdir $DIR/$tdir
4092         chown $RUNAS_ID $DIR/$tdir
4093         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4094                 error "$RUNAS create $tdir/$tfile failed"
4095         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4096                 error "open RDWR" || true
4097 }
4098 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4099
4100 test_33b() {
4101         rm -fr $DIR/$tdir
4102         test_mkdir $DIR/$tdir
4103         chown $RUNAS_ID $DIR/$tdir
4104         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4105 }
4106 run_test 33b "test open file with malformed flags (No panic)"
4107
4108 test_33c() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110         remote_ost_nodsh && skip "remote OST with nodsh"
4111
4112         local ostnum
4113         local ostname
4114         local write_bytes
4115         local all_zeros
4116
4117         all_zeros=true
4118         test_mkdir $DIR/$tdir
4119         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4120
4121         sync
4122         for ostnum in $(seq $OSTCOUNT); do
4123                 # test-framework's OST numbering is one-based, while Lustre's
4124                 # is zero-based
4125                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4126                 # check if at least some write_bytes stats are counted
4127                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4128                               obdfilter.$ostname.stats |
4129                               awk '/^write_bytes/ {print $7}' )
4130                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4131                 if (( ${write_bytes:-0} > 0 )); then
4132                         all_zeros=false
4133                         break
4134                 fi
4135         done
4136
4137         $all_zeros || return 0
4138
4139         # Write four bytes
4140         echo foo > $DIR/$tdir/bar
4141         # Really write them
4142         sync
4143
4144         # Total up write_bytes after writing.  We'd better find non-zeros.
4145         for ostnum in $(seq $OSTCOUNT); do
4146                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4147                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4148                               obdfilter/$ostname/stats |
4149                               awk '/^write_bytes/ {print $7}' )
4150                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4151                 if (( ${write_bytes:-0} > 0 )); then
4152                         all_zeros=false
4153                         break
4154                 fi
4155         done
4156
4157         if $all_zeros; then
4158                 for ostnum in $(seq $OSTCOUNT); do
4159                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4160                         echo "Check write_bytes is in obdfilter.*.stats:"
4161                         do_facet ost$ostnum lctl get_param -n \
4162                                 obdfilter.$ostname.stats
4163                 done
4164                 error "OST not keeping write_bytes stats (b=22312)"
4165         fi
4166 }
4167 run_test 33c "test write_bytes stats"
4168
4169 test_33d() {
4170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172
4173         local MDTIDX=1
4174         local remote_dir=$DIR/$tdir/remote_dir
4175
4176         test_mkdir $DIR/$tdir
4177         $LFS mkdir -i $MDTIDX $remote_dir ||
4178                 error "create remote directory failed"
4179
4180         touch $remote_dir/$tfile
4181         chmod 444 $remote_dir/$tfile
4182         chown $RUNAS_ID $remote_dir/$tfile
4183
4184         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4185
4186         chown $RUNAS_ID $remote_dir
4187         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4188                                         error "create" || true
4189         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4190                                     error "open RDWR" || true
4191         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4192 }
4193 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4194
4195 test_33e() {
4196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4197
4198         mkdir $DIR/$tdir
4199
4200         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4201         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4202         mkdir $DIR/$tdir/local_dir
4203
4204         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4205         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4206         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4207
4208         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4209                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4210
4211         rmdir $DIR/$tdir/* || error "rmdir failed"
4212
4213         umask 777
4214         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4215         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4216         mkdir $DIR/$tdir/local_dir
4217
4218         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4219         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4220         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4221
4222         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4223                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4224
4225         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4226
4227         umask 000
4228         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4229         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4230         mkdir $DIR/$tdir/local_dir
4231
4232         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4233         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4234         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4235
4236         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4237                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4238 }
4239 run_test 33e "mkdir and striped directory should have same mode"
4240
4241 cleanup_33f() {
4242         trap 0
4243         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4244 }
4245
4246 test_33f() {
4247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4248         remote_mds_nodsh && skip "remote MDS with nodsh"
4249
4250         mkdir $DIR/$tdir
4251         chmod go+rwx $DIR/$tdir
4252         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4253         trap cleanup_33f EXIT
4254
4255         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4256                 error "cannot create striped directory"
4257
4258         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4259                 error "cannot create files in striped directory"
4260
4261         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4262                 error "cannot remove files in striped directory"
4263
4264         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4265                 error "cannot remove striped directory"
4266
4267         cleanup_33f
4268 }
4269 run_test 33f "nonroot user can create, access, and remove a striped directory"
4270
4271 test_33g() {
4272         mkdir -p $DIR/$tdir/dir2
4273
4274         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4275         echo $err
4276         [[ $err =~ "exists" ]] || error "Not exists error"
4277 }
4278 run_test 33g "nonroot user create already existing root created file"
4279
4280 sub_33h() {
4281         local hash_type=$1
4282         local count=250
4283
4284         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4285                 error "lfs mkdir -H $hash_type $tdir failed"
4286         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4287
4288         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4289         local index2
4290         local fname
4291
4292         for fname in $DIR/$tdir/$tfile.bak \
4293                      $DIR/$tdir/$tfile.SAV \
4294                      $DIR/$tdir/$tfile.orig \
4295                      $DIR/$tdir/$tfile~; do
4296                 touch $fname || error "touch $fname failed"
4297                 index2=$($LFS getstripe -m $fname)
4298                 (( $index == $index2 )) ||
4299                         error "$fname MDT index mismatch $index != $index2"
4300         done
4301
4302         local failed=0
4303         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4304         local pattern
4305
4306         for pattern in ${patterns[*]}; do
4307                 echo "pattern $pattern"
4308                 fname=$DIR/$tdir/$pattern
4309                 for (( i = 0; i < $count; i++ )); do
4310                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4311                                 error "mktemp $DIR/$tdir/$pattern failed"
4312                         index2=$($LFS getstripe -m $fname)
4313                         (( $index == $index2 )) && continue
4314
4315                         failed=$((failed + 1))
4316                         echo "$fname MDT index mismatch $index != $index2"
4317                 done
4318         done
4319
4320         echo "$failed/$count MDT index mismatches, expect ~2-4"
4321         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4322
4323         local same=0
4324         local expect
4325
4326         # verify that "crush" is still broken with all files on same MDT,
4327         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4328         [[ "$hash_type" == "crush" ]] && expect=$count ||
4329                 expect=$((count / MDSCOUNT))
4330
4331         # crush2 doesn't put all-numeric suffixes on the same MDT,
4332         # filename like $tfile.12345678 should *not* be considered temp
4333         for pattern in ${patterns[*]}; do
4334                 local base=${pattern%%X*}
4335                 local suff=${pattern#$base}
4336
4337                 echo "pattern $pattern"
4338                 for (( i = 0; i < $count; i++ )); do
4339                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4340                         touch $fname || error "touch $fname failed"
4341                         index2=$($LFS getstripe -m $fname)
4342                         (( $index != $index2 )) && continue
4343
4344                         same=$((same + 1))
4345                 done
4346         done
4347
4348         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4349         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4350            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4351                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4352         same=0
4353
4354         # crush2 doesn't put suffixes with special characters on the same MDT
4355         # filename like $tfile.txt.1234 should *not* be considered temp
4356         for pattern in ${patterns[*]}; do
4357                 local base=${pattern%%X*}
4358                 local suff=${pattern#$base}
4359
4360                 pattern=$base...${suff/XXX}
4361                 echo "pattern=$pattern"
4362                 for (( i = 0; i < $count; i++ )); do
4363                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4364                                 error "touch $fname failed"
4365                         index2=$($LFS getstripe -m $fname)
4366                         (( $index != $index2 )) && continue
4367
4368                         same=$((same + 1))
4369                 done
4370         done
4371
4372         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4373         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4374            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4375                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4376 }
4377
4378 test_33h() {
4379         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4380         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4381                 skip "Need MDS version at least 2.13.50"
4382
4383         sub_33h crush
4384 }
4385 run_test 33h "temp file is located on the same MDT as target (crush)"
4386
4387 test_33hh() {
4388         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4389         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4390         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4391                 skip "Need MDS version at least 2.15.0 for crush2"
4392
4393         sub_33h crush2
4394 }
4395 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4396
4397 test_33i()
4398 {
4399         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4400
4401         local FNAME=$(str_repeat 'f' 250)
4402
4403         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4404         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4405
4406         local count
4407         local total
4408
4409         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4410
4411         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4412
4413         lctl --device %$MDC deactivate
4414         stack_trap "lctl --device %$MDC activate"
4415         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4416         total=$(\ls -l $DIR/$tdir | wc -l)
4417         # "ls -l" will list total in the first line
4418         total=$((total - 1))
4419         (( total + count == 1000 )) ||
4420                 error "ls list $total files, $count files on MDT1"
4421 }
4422 run_test 33i "striped directory can be accessed when one MDT is down"
4423
4424 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4425 test_34a() {
4426         rm -f $DIR/f34
4427         $MCREATE $DIR/f34 || error "mcreate failed"
4428         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4429                 error "getstripe failed"
4430         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4431         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4432                 error "getstripe failed"
4433         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4434                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4435 }
4436 run_test 34a "truncate file that has not been opened ==========="
4437
4438 test_34b() {
4439         [ ! -f $DIR/f34 ] && test_34a
4440         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4441                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4442         $OPENFILE -f O_RDONLY $DIR/f34
4443         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4444                 error "getstripe failed"
4445         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4446                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4447 }
4448 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4449
4450 test_34c() {
4451         [ ! -f $DIR/f34 ] && test_34a
4452         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4453                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4454         $OPENFILE -f O_RDWR $DIR/f34
4455         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4456                 error "$LFS getstripe failed"
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459 }
4460 run_test 34c "O_RDWR opening file-with-size works =============="
4461
4462 test_34d() {
4463         [ ! -f $DIR/f34 ] && test_34a
4464         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4465                 error "dd failed"
4466         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4467                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4468         rm $DIR/f34
4469 }
4470 run_test 34d "write to sparse file ============================="
4471
4472 test_34e() {
4473         rm -f $DIR/f34e
4474         $MCREATE $DIR/f34e || error "mcreate failed"
4475         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4476         $CHECKSTAT -s 1000 $DIR/f34e ||
4477                 error "Size of $DIR/f34e not equal to 1000 bytes"
4478         $OPENFILE -f O_RDWR $DIR/f34e
4479         $CHECKSTAT -s 1000 $DIR/f34e ||
4480                 error "Size of $DIR/f34e not equal to 1000 bytes"
4481 }
4482 run_test 34e "create objects, some with size and some without =="
4483
4484 test_34f() { # bug 6242, 6243
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         SIZE34F=48000
4488         rm -f $DIR/f34f
4489         $MCREATE $DIR/f34f || error "mcreate failed"
4490         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4491         dd if=$DIR/f34f of=$TMP/f34f
4492         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4493         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4494         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4495         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4496         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4497 }
4498 run_test 34f "read from a file with no objects until EOF ======="
4499
4500 test_34g() {
4501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4502
4503         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4504                 error "dd failed"
4505         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4506         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4507                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4508         cancel_lru_locks osc
4509         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4510                 error "wrong size after lock cancel"
4511
4512         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4513         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4514                 error "expanding truncate failed"
4515         cancel_lru_locks osc
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4517                 error "wrong expanded size after lock cancel"
4518 }
4519 run_test 34g "truncate long file ==============================="
4520
4521 test_34h() {
4522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4523
4524         local gid=10
4525         local sz=1000
4526
4527         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4528         sync # Flush the cache so that multiop below does not block on cache
4529              # flush when getting the group lock
4530         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4531         MULTIPID=$!
4532
4533         # Since just timed wait is not good enough, let's do a sync write
4534         # that way we are sure enough time for a roundtrip + processing
4535         # passed + 2 seconds of extra margin.
4536         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4537         rm $DIR/${tfile}-1
4538         sleep 2
4539
4540         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4541                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4542                 kill -9 $MULTIPID
4543         fi
4544         wait $MULTIPID
4545         local nsz=`stat -c %s $DIR/$tfile`
4546         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4547 }
4548 run_test 34h "ftruncate file under grouplock should not block"
4549
4550 test_35a() {
4551         cp /bin/sh $DIR/f35a
4552         chmod 444 $DIR/f35a
4553         chown $RUNAS_ID $DIR/f35a
4554         $RUNAS $DIR/f35a && error || true
4555         rm $DIR/f35a
4556 }
4557 run_test 35a "exec file with mode 444 (should return and not leak)"
4558
4559 test_36a() {
4560         rm -f $DIR/f36
4561         utime $DIR/f36 || error "utime failed for MDS"
4562 }
4563 run_test 36a "MDS utime check (mknod, utime)"
4564
4565 test_36b() {
4566         echo "" > $DIR/f36
4567         utime $DIR/f36 || error "utime failed for OST"
4568 }
4569 run_test 36b "OST utime check (open, utime)"
4570
4571 test_36c() {
4572         rm -f $DIR/d36/f36
4573         test_mkdir $DIR/d36
4574         chown $RUNAS_ID $DIR/d36
4575         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4576 }
4577 run_test 36c "non-root MDS utime check (mknod, utime)"
4578
4579 test_36d() {
4580         [ ! -d $DIR/d36 ] && test_36c
4581         echo "" > $DIR/d36/f36
4582         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4583 }
4584 run_test 36d "non-root OST utime check (open, utime)"
4585
4586 test_36e() {
4587         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4588
4589         test_mkdir $DIR/$tdir
4590         touch $DIR/$tdir/$tfile
4591         $RUNAS utime $DIR/$tdir/$tfile &&
4592                 error "utime worked, expected failure" || true
4593 }
4594 run_test 36e "utime on non-owned file (should return error)"
4595
4596 subr_36fh() {
4597         local fl="$1"
4598         local LANG_SAVE=$LANG
4599         local LC_LANG_SAVE=$LC_LANG
4600         export LANG=C LC_LANG=C # for date language
4601
4602         DATESTR="Dec 20  2000"
4603         test_mkdir $DIR/$tdir
4604         lctl set_param fail_loc=$fl
4605         date; date +%s
4606         cp /etc/hosts $DIR/$tdir/$tfile
4607         sync & # write RPC generated with "current" inode timestamp, but delayed
4608         sleep 1
4609         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4610         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4611         cancel_lru_locks $OSC
4612         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4613         date; date +%s
4614         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4615                 echo "BEFORE: $LS_BEFORE" && \
4616                 echo "AFTER : $LS_AFTER" && \
4617                 echo "WANT  : $DATESTR" && \
4618                 error "$DIR/$tdir/$tfile timestamps changed" || true
4619
4620         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4621 }
4622
4623 test_36f() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4627         subr_36fh "0x80000214"
4628 }
4629 run_test 36f "utime on file racing with OST BRW write =========="
4630
4631 test_36g() {
4632         remote_ost_nodsh && skip "remote OST with nodsh"
4633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4635                 skip "Need MDS version at least 2.12.51"
4636
4637         local fmd_max_age
4638         local fmd
4639         local facet="ost1"
4640         local tgt="obdfilter"
4641
4642         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4643
4644         test_mkdir $DIR/$tdir
4645         fmd_max_age=$(do_facet $facet \
4646                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4647                 head -n 1")
4648
4649         echo "FMD max age: ${fmd_max_age}s"
4650         touch $DIR/$tdir/$tfile
4651         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4652                 gawk '{cnt=cnt+$1}  END{print cnt}')
4653         echo "FMD before: $fmd"
4654         [[ $fmd == 0 ]] &&
4655                 error "FMD wasn't create by touch"
4656         sleep $((fmd_max_age + 12))
4657         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4658                 gawk '{cnt=cnt+$1}  END{print cnt}')
4659         echo "FMD after: $fmd"
4660         [[ $fmd == 0 ]] ||
4661                 error "FMD wasn't expired by ping"
4662 }
4663 run_test 36g "FMD cache expiry ====================="
4664
4665 test_36h() {
4666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4667
4668         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4669         subr_36fh "0x80000227"
4670 }
4671 run_test 36h "utime on file racing with OST BRW write =========="
4672
4673 test_36i() {
4674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4675
4676         test_mkdir $DIR/$tdir
4677         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4678
4679         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4680         local new_mtime=$((mtime + 200))
4681
4682         #change Modify time of striped dir
4683         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4684                         error "change mtime failed"
4685
4686         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4687
4688         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4689 }
4690 run_test 36i "change mtime on striped directory"
4691
4692 # test_37 - duplicate with tests 32q 32r
4693
4694 test_38() {
4695         local file=$DIR/$tfile
4696         touch $file
4697         openfile -f O_DIRECTORY $file
4698         local RC=$?
4699         local ENOTDIR=20
4700         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4701         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4702 }
4703 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4704
4705 test_39a() { # was test_39
4706         touch $DIR/$tfile
4707         touch $DIR/${tfile}2
4708 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4710 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4711         sleep 2
4712         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4713         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4714                 echo "mtime"
4715                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4716                 echo "atime"
4717                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4718                 echo "ctime"
4719                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4720                 error "O_TRUNC didn't change timestamps"
4721         fi
4722 }
4723 run_test 39a "mtime changed on create"
4724
4725 test_39b() {
4726         test_mkdir -c1 $DIR/$tdir
4727         cp -p /etc/passwd $DIR/$tdir/fopen
4728         cp -p /etc/passwd $DIR/$tdir/flink
4729         cp -p /etc/passwd $DIR/$tdir/funlink
4730         cp -p /etc/passwd $DIR/$tdir/frename
4731         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4732
4733         sleep 1
4734         echo "aaaaaa" >> $DIR/$tdir/fopen
4735         echo "aaaaaa" >> $DIR/$tdir/flink
4736         echo "aaaaaa" >> $DIR/$tdir/funlink
4737         echo "aaaaaa" >> $DIR/$tdir/frename
4738
4739         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4740         local link_new=`stat -c %Y $DIR/$tdir/flink`
4741         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4742         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4743
4744         cat $DIR/$tdir/fopen > /dev/null
4745         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4746         rm -f $DIR/$tdir/funlink2
4747         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4748
4749         for (( i=0; i < 2; i++ )) ; do
4750                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4751                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4752                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4753                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4754
4755                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4756                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4757                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4758                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4759
4760                 cancel_lru_locks $OSC
4761                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4762         done
4763 }
4764 run_test 39b "mtime change on open, link, unlink, rename  ======"
4765
4766 # this should be set to past
4767 TEST_39_MTIME=`date -d "1 year ago" +%s`
4768
4769 # bug 11063
4770 test_39c() {
4771         touch $DIR1/$tfile
4772         sleep 2
4773         local mtime0=`stat -c %Y $DIR1/$tfile`
4774
4775         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4776         local mtime1=`stat -c %Y $DIR1/$tfile`
4777         [ "$mtime1" = $TEST_39_MTIME ] || \
4778                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4779
4780         local d1=`date +%s`
4781         echo hello >> $DIR1/$tfile
4782         local d2=`date +%s`
4783         local mtime2=`stat -c %Y $DIR1/$tfile`
4784         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4785                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4786
4787         mv $DIR1/$tfile $DIR1/$tfile-1
4788
4789         for (( i=0; i < 2; i++ )) ; do
4790                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4791                 [ "$mtime2" = "$mtime3" ] || \
4792                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4793
4794                 cancel_lru_locks $OSC
4795                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4796         done
4797 }
4798 run_test 39c "mtime change on rename ==========================="
4799
4800 # bug 21114
4801 test_39d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         touch $DIR1/$tfile
4805         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime=`stat -c %Y $DIR1/$tfile`
4809                 [ $mtime = $TEST_39_MTIME ] || \
4810                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39d "create, utime, stat =============================="
4817
4818 # bug 21114
4819 test_39e() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         local mtime1=`stat -c %Y $DIR1/$tfile`
4824
4825         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4826
4827         for (( i=0; i < 2; i++ )) ; do
4828                 local mtime2=`stat -c %Y $DIR1/$tfile`
4829                 [ $mtime2 = $TEST_39_MTIME ] || \
4830                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4831
4832                 cancel_lru_locks $OSC
4833                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4834         done
4835 }
4836 run_test 39e "create, stat, utime, stat ========================"
4837
4838 # bug 21114
4839 test_39f() {
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841
4842         touch $DIR1/$tfile
4843         mtime1=`stat -c %Y $DIR1/$tfile`
4844
4845         sleep 2
4846         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime2=`stat -c %Y $DIR1/$tfile`
4850                 [ $mtime2 = $TEST_39_MTIME ] || \
4851                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39f "create, stat, sleep, utime, stat ================="
4858
4859 # bug 11063
4860 test_39g() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         echo hello >> $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865
4866         sleep 2
4867         chmod o+r $DIR1/$tfile
4868
4869         for (( i=0; i < 2; i++ )) ; do
4870                 local mtime2=`stat -c %Y $DIR1/$tfile`
4871                 [ "$mtime1" = "$mtime2" ] || \
4872                         error "lost mtime: $mtime2, should be $mtime1"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39g "write, chmod, stat ==============================="
4879
4880 # bug 11063
4881 test_39h() {
4882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4883
4884         touch $DIR1/$tfile
4885         sleep 1
4886
4887         local d1=`date`
4888         echo hello >> $DIR1/$tfile
4889         local mtime1=`stat -c %Y $DIR1/$tfile`
4890
4891         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4892         local d2=`date`
4893         if [ "$d1" != "$d2" ]; then
4894                 echo "write and touch not within one second"
4895         else
4896                 for (( i=0; i < 2; i++ )) ; do
4897                         local mtime2=`stat -c %Y $DIR1/$tfile`
4898                         [ "$mtime2" = $TEST_39_MTIME ] || \
4899                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4900
4901                         cancel_lru_locks $OSC
4902                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4903                 done
4904         fi
4905 }
4906 run_test 39h "write, utime within one second, stat ============="
4907
4908 test_39i() {
4909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4910
4911         touch $DIR1/$tfile
4912         sleep 1
4913
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         mv $DIR1/$tfile $DIR1/$tfile-1
4918
4919         for (( i=0; i < 2; i++ )) ; do
4920                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4921
4922                 [ "$mtime1" = "$mtime2" ] || \
4923                         error "lost mtime: $mtime2, should be $mtime1"
4924
4925                 cancel_lru_locks $OSC
4926                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4927         done
4928 }
4929 run_test 39i "write, rename, stat =============================="
4930
4931 test_39j() {
4932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4933
4934         start_full_debug_logging
4935         touch $DIR1/$tfile
4936         sleep 1
4937
4938         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4939         lctl set_param fail_loc=0x80000412
4940         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4941                 error "multiop failed"
4942         local multipid=$!
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         mv $DIR1/$tfile $DIR1/$tfile-1
4946
4947         kill -USR1 $multipid
4948         wait $multipid || error "multiop close failed"
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime1" = "$mtime2" ] ||
4953                         error "mtime is lost on close: $mtime2, " \
4954                               "should be $mtime1"
4955
4956                 cancel_lru_locks
4957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4958         done
4959         lctl set_param fail_loc=0
4960         stop_full_debug_logging
4961 }
4962 run_test 39j "write, rename, close, stat ======================="
4963
4964 test_39k() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         touch $DIR1/$tfile
4968         sleep 1
4969
4970         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4971         local multipid=$!
4972         local mtime1=`stat -c %Y $DIR1/$tfile`
4973
4974         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4975
4976         kill -USR1 $multipid
4977         wait $multipid || error "multiop close failed"
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime2=`stat -c %Y $DIR1/$tfile`
4981
4982                 [ "$mtime2" = $TEST_39_MTIME ] || \
4983                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4984
4985                 cancel_lru_locks
4986                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987         done
4988 }
4989 run_test 39k "write, utime, close, stat ========================"
4990
4991 # this should be set to future
4992 TEST_39_ATIME=`date -d "1 year" +%s`
4993
4994 test_39l() {
4995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4996         remote_mds_nodsh && skip "remote MDS with nodsh"
4997
4998         local atime_diff=$(do_facet $SINGLEMDS \
4999                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5000         rm -rf $DIR/$tdir
5001         mkdir_on_mdt0 $DIR/$tdir
5002
5003         # test setting directory atime to future
5004         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5005         local atime=$(stat -c %X $DIR/$tdir)
5006         [ "$atime" = $TEST_39_ATIME ] ||
5007                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5008
5009         # test setting directory atime from future to now
5010         local now=$(date +%s)
5011         touch -a -d @$now $DIR/$tdir
5012
5013         atime=$(stat -c %X $DIR/$tdir)
5014         [ "$atime" -eq "$now"  ] ||
5015                 error "atime is not updated from future: $atime, $now"
5016
5017         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5018         sleep 3
5019
5020         # test setting directory atime when now > dir atime + atime_diff
5021         local d1=$(date +%s)
5022         ls $DIR/$tdir
5023         local d2=$(date +%s)
5024         cancel_lru_locks mdc
5025         atime=$(stat -c %X $DIR/$tdir)
5026         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5027                 error "atime is not updated  : $atime, should be $d2"
5028
5029         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5030         sleep 3
5031
5032         # test not setting directory atime when now < dir atime + atime_diff
5033         ls $DIR/$tdir
5034         cancel_lru_locks mdc
5035         atime=$(stat -c %X $DIR/$tdir)
5036         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5037                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5038
5039         do_facet $SINGLEMDS \
5040                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5041 }
5042 run_test 39l "directory atime update ==========================="
5043
5044 test_39m() {
5045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5046
5047         touch $DIR1/$tfile
5048         sleep 2
5049         local far_past_mtime=$(date -d "May 29 1953" +%s)
5050         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5051
5052         touch -m -d @$far_past_mtime $DIR1/$tfile
5053         touch -a -d @$far_past_atime $DIR1/$tfile
5054
5055         for (( i=0; i < 2; i++ )) ; do
5056                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5057                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5058                         error "atime or mtime set incorrectly"
5059
5060                 cancel_lru_locks $OSC
5061                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5062         done
5063 }
5064 run_test 39m "test atime and mtime before 1970"
5065
5066 test_39n() { # LU-3832
5067         remote_mds_nodsh && skip "remote MDS with nodsh"
5068
5069         local atime_diff=$(do_facet $SINGLEMDS \
5070                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5071         local atime0
5072         local atime1
5073         local atime2
5074
5075         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5076
5077         rm -rf $DIR/$tfile
5078         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5079         atime0=$(stat -c %X $DIR/$tfile)
5080
5081         sleep 5
5082         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5083         atime1=$(stat -c %X $DIR/$tfile)
5084
5085         sleep 5
5086         cancel_lru_locks mdc
5087         cancel_lru_locks osc
5088         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5089         atime2=$(stat -c %X $DIR/$tfile)
5090
5091         do_facet $SINGLEMDS \
5092                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5093
5094         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5095         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5096 }
5097 run_test 39n "check that O_NOATIME is honored"
5098
5099 test_39o() {
5100         TESTDIR=$DIR/$tdir/$tfile
5101         [ -e $TESTDIR ] && rm -rf $TESTDIR
5102         mkdir -p $TESTDIR
5103         cd $TESTDIR
5104         links1=2
5105         ls
5106         mkdir a b
5107         ls
5108         links2=$(stat -c %h .)
5109         [ $(($links1 + 2)) != $links2 ] &&
5110                 error "wrong links count $(($links1 + 2)) != $links2"
5111         rmdir b
5112         links3=$(stat -c %h .)
5113         [ $(($links1 + 1)) != $links3 ] &&
5114                 error "wrong links count $links1 != $links3"
5115         return 0
5116 }
5117 run_test 39o "directory cached attributes updated after create"
5118
5119 test_39p() {
5120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5121
5122         local MDTIDX=1
5123         TESTDIR=$DIR/$tdir/$tdir
5124         [ -e $TESTDIR ] && rm -rf $TESTDIR
5125         test_mkdir -p $TESTDIR
5126         cd $TESTDIR
5127         links1=2
5128         ls
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5130         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5131         ls
5132         links2=$(stat -c %h .)
5133         [ $(($links1 + 2)) != $links2 ] &&
5134                 error "wrong links count $(($links1 + 2)) != $links2"
5135         rmdir remote_dir2
5136         links3=$(stat -c %h .)
5137         [ $(($links1 + 1)) != $links3 ] &&
5138                 error "wrong links count $links1 != $links3"
5139         return 0
5140 }
5141 run_test 39p "remote directory cached attributes updated after create ========"
5142
5143 test_39r() {
5144         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5145                 skip "no atime update on old OST"
5146         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5147                 skip_env "ldiskfs only test"
5148         fi
5149
5150         local saved_adiff
5151         saved_adiff=$(do_facet ost1 \
5152                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5153         stack_trap "do_facet ost1 \
5154                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5155
5156         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5157
5158         $LFS setstripe -i 0 $DIR/$tfile
5159         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5160                 error "can't write initial file"
5161         cancel_lru_locks osc
5162
5163         # exceed atime_diff and access file
5164         sleep 10
5165         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5166                 error "can't udpate atime"
5167
5168         local atime_cli=$(stat -c %X $DIR/$tfile)
5169         echo "client atime: $atime_cli"
5170         # allow atime update to be written to device
5171         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5172         sleep 5
5173
5174         local ostdev=$(ostdevname 1)
5175         local fid=($(lfs getstripe -y $DIR/$tfile |
5176                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5177         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5178         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5179
5180         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5181         local atime_ost=$(do_facet ost1 "$cmd" |&
5182                           awk -F'[: ]' '/atime:/ { print $4 }')
5183         (( atime_cli == atime_ost )) ||
5184                 error "atime on client $atime_cli != ost $atime_ost"
5185 }
5186 run_test 39r "lazy atime update on OST"
5187
5188 test_39q() { # LU-8041
5189         local testdir=$DIR/$tdir
5190         mkdir -p $testdir
5191         multiop_bg_pause $testdir D_c || error "multiop failed"
5192         local multipid=$!
5193         cancel_lru_locks mdc
5194         kill -USR1 $multipid
5195         local atime=$(stat -c %X $testdir)
5196         [ "$atime" -ne 0 ] || error "atime is zero"
5197 }
5198 run_test 39q "close won't zero out atime"
5199
5200 test_40() {
5201         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5202         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5203                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5204         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5205                 error "$tfile is not 4096 bytes in size"
5206 }
5207 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5208
5209 test_41() {
5210         # bug 1553
5211         small_write $DIR/f41 18
5212 }
5213 run_test 41 "test small file write + fstat ====================="
5214
5215 count_ost_writes() {
5216         lctl get_param -n ${OSC}.*.stats |
5217                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5218                         END { printf("%0.0f", writes) }'
5219 }
5220
5221 # decent default
5222 WRITEBACK_SAVE=500
5223 DIRTY_RATIO_SAVE=40
5224 MAX_DIRTY_RATIO=50
5225 BG_DIRTY_RATIO_SAVE=10
5226 MAX_BG_DIRTY_RATIO=25
5227
5228 start_writeback() {
5229         trap 0
5230         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5231         # dirty_ratio, dirty_background_ratio
5232         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5233                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5234                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5235                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5236         else
5237                 # if file not here, we are a 2.4 kernel
5238                 kill -CONT `pidof kupdated`
5239         fi
5240 }
5241
5242 stop_writeback() {
5243         # setup the trap first, so someone cannot exit the test at the
5244         # exact wrong time and mess up a machine
5245         trap start_writeback EXIT
5246         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5247         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5248                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 sysctl -w vm.dirty_writeback_centisecs=0
5251                 # save and increase /proc/sys/vm/dirty_ratio
5252                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5253                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5254                 # save and increase /proc/sys/vm/dirty_background_ratio
5255                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5256                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5257         else
5258                 # if file not here, we are a 2.4 kernel
5259                 kill -STOP `pidof kupdated`
5260         fi
5261 }
5262
5263 # ensure that all stripes have some grant before we test client-side cache
5264 setup_test42() {
5265         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5266                 dd if=/dev/zero of=$i bs=4k count=1
5267                 rm $i
5268         done
5269 }
5270
5271 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5272 # file truncation, and file removal.
5273 test_42a() {
5274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5275
5276         setup_test42
5277         cancel_lru_locks $OSC
5278         stop_writeback
5279         sync; sleep 1; sync # just to be safe
5280         BEFOREWRITES=`count_ost_writes`
5281         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5282         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5283         AFTERWRITES=`count_ost_writes`
5284         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5285                 error "$BEFOREWRITES < $AFTERWRITES"
5286         start_writeback
5287 }
5288 run_test 42a "ensure that we don't flush on close"
5289
5290 test_42b() {
5291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5292
5293         setup_test42
5294         cancel_lru_locks $OSC
5295         stop_writeback
5296         sync
5297         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5298         BEFOREWRITES=$(count_ost_writes)
5299         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5300         AFTERWRITES=$(count_ost_writes)
5301         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5302                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5303         fi
5304         BEFOREWRITES=$(count_ost_writes)
5305         sync || error "sync: $?"
5306         AFTERWRITES=$(count_ost_writes)
5307         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5308                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5309         fi
5310         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5311         start_writeback
5312         return 0
5313 }
5314 run_test 42b "test destroy of file with cached dirty data ======"
5315
5316 # if these tests just want to test the effect of truncation,
5317 # they have to be very careful.  consider:
5318 # - the first open gets a {0,EOF}PR lock
5319 # - the first write conflicts and gets a {0, count-1}PW
5320 # - the rest of the writes are under {count,EOF}PW
5321 # - the open for truncate tries to match a {0,EOF}PR
5322 #   for the filesize and cancels the PWs.
5323 # any number of fixes (don't get {0,EOF} on open, match
5324 # composite locks, do smarter file size management) fix
5325 # this, but for now we want these tests to verify that
5326 # the cancellation with truncate intent works, so we
5327 # start the file with a full-file pw lock to match against
5328 # until the truncate.
5329 trunc_test() {
5330         test=$1
5331         file=$DIR/$test
5332         offset=$2
5333         cancel_lru_locks $OSC
5334         stop_writeback
5335         # prime the file with 0,EOF PW to match
5336         touch $file
5337         $TRUNCATE $file 0
5338         sync; sync
5339         # now the real test..
5340         dd if=/dev/zero of=$file bs=1024 count=100
5341         BEFOREWRITES=`count_ost_writes`
5342         $TRUNCATE $file $offset
5343         cancel_lru_locks $OSC
5344         AFTERWRITES=`count_ost_writes`
5345         start_writeback
5346 }
5347
5348 test_42c() {
5349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5350
5351         trunc_test 42c 1024
5352         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5353                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5354         rm $file
5355 }
5356 run_test 42c "test partial truncate of file with cached dirty data"
5357
5358 test_42d() {
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5362         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5363         $LCTL set_param debug=+cache
5364
5365         trunc_test 42d 0
5366         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5367                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5368         rm $file
5369 }
5370 run_test 42d "test complete truncate of file with cached dirty data"
5371
5372 test_42e() { # bug22074
5373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5374
5375         local TDIR=$DIR/${tdir}e
5376         local pages=16 # hardcoded 16 pages, don't change it.
5377         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5378         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5379         local max_dirty_mb
5380         local warmup_files
5381
5382         test_mkdir $DIR/${tdir}e
5383         $LFS setstripe -c 1 $TDIR
5384         createmany -o $TDIR/f $files
5385
5386         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5387
5388         # we assume that with $OSTCOUNT files, at least one of them will
5389         # be allocated on OST0.
5390         warmup_files=$((OSTCOUNT * max_dirty_mb))
5391         createmany -o $TDIR/w $warmup_files
5392
5393         # write a large amount of data into one file and sync, to get good
5394         # avail_grant number from OST.
5395         for ((i=0; i<$warmup_files; i++)); do
5396                 idx=$($LFS getstripe -i $TDIR/w$i)
5397                 [ $idx -ne 0 ] && continue
5398                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5399                 break
5400         done
5401         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5402         sync
5403         $LCTL get_param $proc_osc0/cur_dirty_bytes
5404         $LCTL get_param $proc_osc0/cur_grant_bytes
5405
5406         # create as much dirty pages as we can while not to trigger the actual
5407         # RPCs directly. but depends on the env, VFS may trigger flush during this
5408         # period, hopefully we are good.
5409         for ((i=0; i<$warmup_files; i++)); do
5410                 idx=$($LFS getstripe -i $TDIR/w$i)
5411                 [ $idx -ne 0 ] && continue
5412                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5413         done
5414         $LCTL get_param $proc_osc0/cur_dirty_bytes
5415         $LCTL get_param $proc_osc0/cur_grant_bytes
5416
5417         # perform the real test
5418         $LCTL set_param $proc_osc0/rpc_stats 0
5419         for ((;i<$files; i++)); do
5420                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5421                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5422         done
5423         sync
5424         $LCTL get_param $proc_osc0/rpc_stats
5425
5426         local percent=0
5427         local have_ppr=false
5428         $LCTL get_param $proc_osc0/rpc_stats |
5429                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5430                         # skip lines until we are at the RPC histogram data
5431                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5432                         $have_ppr || continue
5433
5434                         # we only want the percent stat for < 16 pages
5435                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5436
5437                         percent=$((percent + WPCT))
5438                         if [[ $percent -gt 15 ]]; then
5439                                 error "less than 16-pages write RPCs" \
5440                                       "$percent% > 15%"
5441                                 break
5442                         fi
5443                 done
5444         rm -rf $TDIR
5445 }
5446 run_test 42e "verify sub-RPC writes are not done synchronously"
5447
5448 test_43A() { # was test_43
5449         test_mkdir $DIR/$tdir
5450         cp -p /bin/ls $DIR/$tdir/$tfile
5451         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5452         pid=$!
5453         # give multiop a chance to open
5454         sleep 1
5455
5456         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5457         kill -USR1 $pid
5458         # Wait for multiop to exit
5459         wait $pid
5460 }
5461 run_test 43A "execution of file opened for write should return -ETXTBSY"
5462
5463 test_43a() {
5464         test_mkdir $DIR/$tdir
5465         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5466         $DIR/$tdir/sleep 60 &
5467         SLEEP_PID=$!
5468         # Make sure exec of $tdir/sleep wins race with truncate
5469         sleep 1
5470         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5471         kill $SLEEP_PID
5472 }
5473 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5474
5475 test_43b() {
5476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5477
5478         test_mkdir $DIR/$tdir
5479         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5480         $DIR/$tdir/sleep 60 &
5481         SLEEP_PID=$!
5482         # Make sure exec of $tdir/sleep wins race with truncate
5483         sleep 1
5484         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5485         kill $SLEEP_PID
5486 }
5487 run_test 43b "truncate of file being executed should return -ETXTBSY"
5488
5489 test_43c() {
5490         local testdir="$DIR/$tdir"
5491         test_mkdir $testdir
5492         cp $SHELL $testdir/
5493         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5494                 ( cd $testdir && md5sum -c )
5495 }
5496 run_test 43c "md5sum of copy into lustre"
5497
5498 test_44A() { # was test_44
5499         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5500
5501         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5502         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5503 }
5504 run_test 44A "zero length read from a sparse stripe"
5505
5506 test_44a() {
5507         local nstripe=$($LFS getstripe -c -d $DIR)
5508         [ -z "$nstripe" ] && skip "can't get stripe info"
5509         [[ $nstripe -gt $OSTCOUNT ]] &&
5510                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5511
5512         local stride=$($LFS getstripe -S -d $DIR)
5513         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5514                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5515         fi
5516
5517         OFFSETS="0 $((stride/2)) $((stride-1))"
5518         for offset in $OFFSETS; do
5519                 for i in $(seq 0 $((nstripe-1))); do
5520                         local GLOBALOFFSETS=""
5521                         # size in Bytes
5522                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5523                         local myfn=$DIR/d44a-$size
5524                         echo "--------writing $myfn at $size"
5525                         ll_sparseness_write $myfn $size ||
5526                                 error "ll_sparseness_write"
5527                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5528                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5529                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5530
5531                         for j in $(seq 0 $((nstripe-1))); do
5532                                 # size in Bytes
5533                                 size=$((((j + $nstripe )*$stride + $offset)))
5534                                 ll_sparseness_write $myfn $size ||
5535                                         error "ll_sparseness_write"
5536                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5537                         done
5538                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5539                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5540                         rm -f $myfn
5541                 done
5542         done
5543 }
5544 run_test 44a "test sparse pwrite ==============================="
5545
5546 dirty_osc_total() {
5547         tot=0
5548         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5549                 tot=$(($tot + $d))
5550         done
5551         echo $tot
5552 }
5553 do_dirty_record() {
5554         before=`dirty_osc_total`
5555         echo executing "\"$*\""
5556         eval $*
5557         after=`dirty_osc_total`
5558         echo before $before, after $after
5559 }
5560 test_45() {
5561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5562
5563         f="$DIR/f45"
5564         # Obtain grants from OST if it supports it
5565         echo blah > ${f}_grant
5566         stop_writeback
5567         sync
5568         do_dirty_record "echo blah > $f"
5569         [[ $before -eq $after ]] && error "write wasn't cached"
5570         do_dirty_record "> $f"
5571         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5572         do_dirty_record "echo blah > $f"
5573         [[ $before -eq $after ]] && error "write wasn't cached"
5574         do_dirty_record "sync"
5575         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5576         do_dirty_record "echo blah > $f"
5577         [[ $before -eq $after ]] && error "write wasn't cached"
5578         do_dirty_record "cancel_lru_locks osc"
5579         [[ $before -gt $after ]] ||
5580                 error "lock cancellation didn't lower dirty count"
5581         start_writeback
5582 }
5583 run_test 45 "osc io page accounting ============================"
5584
5585 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5586 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5587 # objects offset and an assert hit when an rpc was built with 1023's mapped
5588 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5589 test_46() {
5590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5591
5592         f="$DIR/f46"
5593         stop_writeback
5594         sync
5595         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5596         sync
5597         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5598         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5599         sync
5600         start_writeback
5601 }
5602 run_test 46 "dirtying a previously written page ================"
5603
5604 # test_47 is removed "Device nodes check" is moved to test_28
5605
5606 test_48a() { # bug 2399
5607         [ "$mds1_FSTYPE" = "zfs" ] &&
5608         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5609                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5610
5611         test_mkdir $DIR/$tdir
5612         cd $DIR/$tdir
5613         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5614         test_mkdir $DIR/$tdir
5615         touch foo || error "'touch foo' failed after recreating cwd"
5616         test_mkdir bar
5617         touch .foo || error "'touch .foo' failed after recreating cwd"
5618         test_mkdir .bar
5619         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5620         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5621         cd . || error "'cd .' failed after recreating cwd"
5622         mkdir . && error "'mkdir .' worked after recreating cwd"
5623         rmdir . && error "'rmdir .' worked after recreating cwd"
5624         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5625         cd .. || error "'cd ..' failed after recreating cwd"
5626 }
5627 run_test 48a "Access renamed working dir (should return errors)="
5628
5629 test_48b() { # bug 2399
5630         rm -rf $DIR/$tdir
5631         test_mkdir $DIR/$tdir
5632         cd $DIR/$tdir
5633         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5634         touch foo && error "'touch foo' worked after removing cwd"
5635         mkdir foo && error "'mkdir foo' worked after removing cwd"
5636         touch .foo && error "'touch .foo' worked after removing cwd"
5637         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5638         ls . > /dev/null && error "'ls .' worked after removing cwd"
5639         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5640         mkdir . && error "'mkdir .' worked after removing cwd"
5641         rmdir . && error "'rmdir .' worked after removing cwd"
5642         ln -s . foo && error "'ln -s .' worked after removing cwd"
5643         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5644 }
5645 run_test 48b "Access removed working dir (should return errors)="
5646
5647 test_48c() { # bug 2350
5648         #lctl set_param debug=-1
5649         #set -vx
5650         rm -rf $DIR/$tdir
5651         test_mkdir -p $DIR/$tdir/dir
5652         cd $DIR/$tdir/dir
5653         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5654         $TRACE touch foo && error "touch foo worked after removing cwd"
5655         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5656         touch .foo && error "touch .foo worked after removing cwd"
5657         mkdir .foo && error "mkdir .foo worked after removing cwd"
5658         $TRACE ls . && error "'ls .' worked after removing cwd"
5659         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5660         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5661         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5662         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5663         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5664 }
5665 run_test 48c "Access removed working subdir (should return errors)"
5666
5667 test_48d() { # bug 2350
5668         #lctl set_param debug=-1
5669         #set -vx
5670         rm -rf $DIR/$tdir
5671         test_mkdir -p $DIR/$tdir/dir
5672         cd $DIR/$tdir/dir
5673         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5674         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5675         $TRACE touch foo && error "'touch foo' worked after removing parent"
5676         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5677         touch .foo && error "'touch .foo' worked after removing parent"
5678         mkdir .foo && error "mkdir .foo worked after removing parent"
5679         $TRACE ls . && error "'ls .' worked after removing parent"
5680         $TRACE ls .. && error "'ls ..' worked after removing parent"
5681         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5682         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5683         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5684         true
5685 }
5686 run_test 48d "Access removed parent subdir (should return errors)"
5687
5688 test_48e() { # bug 4134
5689         #lctl set_param debug=-1
5690         #set -vx
5691         rm -rf $DIR/$tdir
5692         test_mkdir -p $DIR/$tdir/dir
5693         cd $DIR/$tdir/dir
5694         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5695         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5696         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5697         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5698         # On a buggy kernel addition of "touch foo" after cd .. will
5699         # produce kernel oops in lookup_hash_it
5700         touch ../foo && error "'cd ..' worked after recreate parent"
5701         cd $DIR
5702         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5703 }
5704 run_test 48e "Access to recreated parent subdir (should return errors)"
5705
5706 test_48f() {
5707         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5708                 skip "need MDS >= 2.13.55"
5709         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5710         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5711                 skip "needs different host for mdt1 mdt2"
5712         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5713
5714         $LFS mkdir -i0 $DIR/$tdir
5715         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5716
5717         for d in sub1 sub2 sub3; do
5718                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5719                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5720                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5721         done
5722
5723         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5724 }
5725 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5726
5727 test_49() { # LU-1030
5728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5729         remote_ost_nodsh && skip "remote OST with nodsh"
5730
5731         # get ost1 size - $FSNAME-OST0000
5732         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5733                 awk '{ print $4 }')
5734         # write 800M at maximum
5735         [[ $ost1_size -lt 2 ]] && ost1_size=2
5736         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5737
5738         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5739         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5740         local dd_pid=$!
5741
5742         # change max_pages_per_rpc while writing the file
5743         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5744         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5745         # loop until dd process exits
5746         while ps ax -opid | grep -wq $dd_pid; do
5747                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5748                 sleep $((RANDOM % 5 + 1))
5749         done
5750         # restore original max_pages_per_rpc
5751         $LCTL set_param $osc1_mppc=$orig_mppc
5752         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5753 }
5754 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5755
5756 test_50() {
5757         # bug 1485
5758         test_mkdir $DIR/$tdir
5759         cd $DIR/$tdir
5760         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5761 }
5762 run_test 50 "special situations: /proc symlinks  ==============="
5763
5764 test_51a() {    # was test_51
5765         # bug 1516 - create an empty entry right after ".." then split dir
5766         test_mkdir -c1 $DIR/$tdir
5767         touch $DIR/$tdir/foo
5768         $MCREATE $DIR/$tdir/bar
5769         rm $DIR/$tdir/foo
5770         createmany -m $DIR/$tdir/longfile 201
5771         FNUM=202
5772         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5773                 $MCREATE $DIR/$tdir/longfile$FNUM
5774                 FNUM=$(($FNUM + 1))
5775                 echo -n "+"
5776         done
5777         echo
5778         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5779 }
5780 run_test 51a "special situations: split htree with empty entry =="
5781
5782 cleanup_print_lfs_df () {
5783         trap 0
5784         $LFS df
5785         $LFS df -i
5786 }
5787
5788 test_51b() {
5789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5790
5791         local dir=$DIR/$tdir
5792         local nrdirs=$((65536 + 100))
5793
5794         # cleanup the directory
5795         rm -fr $dir
5796
5797         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5798
5799         $LFS df
5800         $LFS df -i
5801         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5802         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5803         [[ $numfree -lt $nrdirs ]] &&
5804                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5805
5806         # need to check free space for the directories as well
5807         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5808         numfree=$(( blkfree / $(fs_inode_ksize) ))
5809         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5810
5811         trap cleanup_print_lfs_df EXIT
5812
5813         # create files
5814         createmany -d $dir/d $nrdirs || {
5815                 unlinkmany $dir/d $nrdirs
5816                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5817         }
5818
5819         # really created :
5820         nrdirs=$(ls -U $dir | wc -l)
5821
5822         # unlink all but 100 subdirectories, then check it still works
5823         local left=100
5824         local delete=$((nrdirs - left))
5825
5826         $LFS df
5827         $LFS df -i
5828
5829         # for ldiskfs the nlink count should be 1, but this is OSD specific
5830         # and so this is listed for informational purposes only
5831         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5832         unlinkmany -d $dir/d $delete ||
5833                 error "unlink of first $delete subdirs failed"
5834
5835         echo "nlink between: $(stat -c %h $dir)"
5836         local found=$(ls -U $dir | wc -l)
5837         [ $found -ne $left ] &&
5838                 error "can't find subdirs: found only $found, expected $left"
5839
5840         unlinkmany -d $dir/d $delete $left ||
5841                 error "unlink of second $left subdirs failed"
5842         # regardless of whether the backing filesystem tracks nlink accurately
5843         # or not, the nlink count shouldn't be more than "." and ".." here
5844         local after=$(stat -c %h $dir)
5845         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5846                 echo "nlink after: $after"
5847
5848         cleanup_print_lfs_df
5849 }
5850 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5851
5852 test_51d_sub() {
5853         local stripecount=$1
5854         local nfiles=$2
5855
5856         log "create files with stripecount=$stripecount"
5857         $LFS setstripe -C $stripecount $DIR/$tdir
5858         createmany -o $DIR/$tdir/t- $nfiles
5859         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5860         for ((n = 0; n < $OSTCOUNT; n++)); do
5861                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5862                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5863                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5864                             '($1 == '$n') { objs += 1 } \
5865                             END { printf("%0.0f", objs) }')
5866                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5867         done
5868         unlinkmany $DIR/$tdir/t- $nfiles
5869         rm  -f $TMP/$tfile
5870
5871         local nlast
5872         local min=4
5873         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5874
5875         # For some combinations of stripecount and OSTCOUNT current code
5876         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5877         # than others. Rather than skipping this test entirely, check that
5878         # and keep testing to ensure imbalance does not get worse. LU-15282
5879         (( (OSTCOUNT == 6 && stripecount == 4) ||
5880            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5881            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5882         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5883                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5884                         { $LFS df && $LFS df -i &&
5885                         error "stripecount=$stripecount: " \
5886                               "OST $n has fewer objects vs. OST $nlast " \
5887                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5888                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5889                         { $LFS df && $LFS df -i &&
5890                         error "stripecount=$stripecount: " \
5891                               "OST $n has more objects vs. OST $nlast " \
5892                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5893
5894                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5895                         { $LFS df && $LFS df -i &&
5896                         error "stripecount=$stripecount: " \
5897                               "OST $n has fewer #0 objects vs. OST $nlast " \
5898                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5899                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5900                         { $LFS df && $LFS df -i &&
5901                         error "stripecount=$stripecount: " \
5902                               "OST $n has more #0 objects vs. OST $nlast " \
5903                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5904         done
5905 }
5906
5907 test_51d() {
5908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5909         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5910
5911         local stripecount
5912         local per_ost=100
5913         local nfiles=$((per_ost * OSTCOUNT))
5914         local mdts=$(comma_list $(mdts_nodes))
5915         local param="osp.*.create_count"
5916         local qos_old=$(do_facet mds1 \
5917                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5918
5919         do_nodes $mdts \
5920                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5921         stack_trap "do_nodes $mdts \
5922                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5923
5924         test_mkdir $DIR/$tdir
5925         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5926
5927         # Ensure enough OST objects precreated for tests to pass without
5928         # running out of objects.  This is an LOV r-r OST algorithm test,
5929         # not an OST object precreation test.
5930         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5931         (( old >= nfiles )) ||
5932         {
5933                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5934
5935                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5936                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5937
5938                 # trigger precreation from all MDTs for all OSTs
5939                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5940                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5941                 done
5942         }
5943
5944         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5945                 sleep 8  # allow object precreation to catch up
5946                 test_51d_sub $stripecount $nfiles
5947         done
5948 }
5949 run_test 51d "check LOV round-robin OST object distribution"
5950
5951 test_51e() {
5952         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5953                 skip_env "ldiskfs only test"
5954         fi
5955
5956         test_mkdir -c1 $DIR/$tdir
5957         test_mkdir -c1 $DIR/$tdir/d0
5958
5959         touch $DIR/$tdir/d0/foo
5960         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5961                 error "file exceed 65000 nlink limit!"
5962         unlinkmany $DIR/$tdir/d0/f- 65001
5963         return 0
5964 }
5965 run_test 51e "check file nlink limit"
5966
5967 test_51f() {
5968         test_mkdir $DIR/$tdir
5969
5970         local max=100000
5971         local ulimit_old=$(ulimit -n)
5972         local spare=20 # number of spare fd's for scripts/libraries, etc.
5973         local mdt=$($LFS getstripe -m $DIR/$tdir)
5974         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5975
5976         echo "MDT$mdt numfree=$numfree, max=$max"
5977         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5978         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5979                 while ! ulimit -n $((numfree + spare)); do
5980                         numfree=$((numfree * 3 / 4))
5981                 done
5982                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5983         else
5984                 echo "left ulimit at $ulimit_old"
5985         fi
5986
5987         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5988                 unlinkmany $DIR/$tdir/f $numfree
5989                 error "create+open $numfree files in $DIR/$tdir failed"
5990         }
5991         ulimit -n $ulimit_old
5992
5993         # if createmany exits at 120s there will be fewer than $numfree files
5994         unlinkmany $DIR/$tdir/f $numfree || true
5995 }
5996 run_test 51f "check many open files limit"
5997
5998 test_52a() {
5999         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6000         test_mkdir $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6003         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6004         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6005         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6006         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6007                                         error "link worked"
6008         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6009         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6010         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6011                                                      error "lsattr"
6012         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6013         cp -r $DIR/$tdir $TMP/
6014         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6015 }
6016 run_test 52a "append-only flag test (should return errors)"
6017
6018 test_52b() {
6019         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6020         test_mkdir $DIR/$tdir
6021         touch $DIR/$tdir/foo
6022         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6023         cat test > $DIR/$tdir/foo && error "cat test worked"
6024         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6025         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6026         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6027                                         error "link worked"
6028         echo foo >> $DIR/$tdir/foo && error "echo worked"
6029         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6030         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6031         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6032         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6033                                                         error "lsattr"
6034         chattr -i $DIR/$tdir/foo || error "chattr failed"
6035
6036         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6037 }
6038 run_test 52b "immutable flag test (should return errors) ======="
6039
6040 test_53() {
6041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6042         remote_mds_nodsh && skip "remote MDS with nodsh"
6043         remote_ost_nodsh && skip "remote OST with nodsh"
6044
6045         local param
6046         local param_seq
6047         local ostname
6048         local mds_last
6049         local mds_last_seq
6050         local ost_last
6051         local ost_last_seq
6052         local ost_last_id
6053         local ostnum
6054         local node
6055         local found=false
6056         local support_last_seq=true
6057
6058         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6059                 support_last_seq=false
6060
6061         # only test MDT0000
6062         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6063         local value
6064         for value in $(do_facet $SINGLEMDS \
6065                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6066                 param=$(echo ${value[0]} | cut -d "=" -f1)
6067                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6068
6069                 if $support_last_seq; then
6070                         param_seq=$(echo $param |
6071                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6072                         mds_last_seq=$(do_facet $SINGLEMDS \
6073                                        $LCTL get_param -n $param_seq)
6074                 fi
6075                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6076
6077                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6078                 node=$(facet_active_host ost$((ostnum+1)))
6079                 param="obdfilter.$ostname.last_id"
6080                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6081                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6082                         ost_last_id=$ost_last
6083
6084                         if $support_last_seq; then
6085                                 ost_last_id=$(echo $ost_last |
6086                                               awk -F':' '{print $2}' |
6087                                               sed -e "s/^0x//g")
6088                                 ost_last_seq=$(echo $ost_last |
6089                                                awk -F':' '{print $1}')
6090                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6091                         fi
6092
6093                         if [[ $ost_last_id != $mds_last ]]; then
6094                                 error "$ost_last_id != $mds_last"
6095                         else
6096                                 found=true
6097                                 break
6098                         fi
6099                 done
6100         done
6101         $found || error "can not match last_seq/last_id for $mdtosc"
6102         return 0
6103 }
6104 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6105
6106 test_54a() {
6107         perl -MSocket -e ';' || skip "no Socket perl module installed"
6108
6109         $SOCKETSERVER $DIR/socket ||
6110                 error "$SOCKETSERVER $DIR/socket failed: $?"
6111         $SOCKETCLIENT $DIR/socket ||
6112                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6113         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6114 }
6115 run_test 54a "unix domain socket test =========================="
6116
6117 test_54b() {
6118         f="$DIR/f54b"
6119         mknod $f c 1 3
6120         chmod 0666 $f
6121         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6122 }
6123 run_test 54b "char device works in lustre ======================"
6124
6125 find_loop_dev() {
6126         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6127         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6128         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6129
6130         for i in $(seq 3 7); do
6131                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6132                 LOOPDEV=$LOOPBASE$i
6133                 LOOPNUM=$i
6134                 break
6135         done
6136 }
6137
6138 cleanup_54c() {
6139         local rc=0
6140         loopdev="$DIR/loop54c"
6141
6142         trap 0
6143         $UMOUNT $DIR/$tdir || rc=$?
6144         losetup -d $loopdev || true
6145         losetup -d $LOOPDEV || true
6146         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6147         return $rc
6148 }
6149
6150 test_54c() {
6151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6152
6153         loopdev="$DIR/loop54c"
6154
6155         find_loop_dev
6156         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6157         trap cleanup_54c EXIT
6158         mknod $loopdev b 7 $LOOPNUM
6159         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6161         losetup $loopdev $DIR/$tfile ||
6162                 error "can't set up $loopdev for $DIR/$tfile"
6163         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6164         test_mkdir $DIR/$tdir
6165         mount -t ext2 $loopdev $DIR/$tdir ||
6166                 error "error mounting $loopdev on $DIR/$tdir"
6167         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6168                 error "dd write"
6169         df $DIR/$tdir
6170         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6171                 error "dd read"
6172         cleanup_54c
6173 }
6174 run_test 54c "block device works in lustre ====================="
6175
6176 test_54d() {
6177         local pipe="$DIR/$tfile.pipe"
6178         local string="aaaaaa"
6179
6180         mknod $pipe p
6181         echo -n "$string" > $pipe &
6182         local result=$(cat $pipe)
6183         [[ "$result" == "$string" ]] || error "$result != $string"
6184 }
6185 run_test 54d "fifo device works in lustre ======================"
6186
6187 test_54e() {
6188         f="$DIR/f54e"
6189         string="aaaaaa"
6190         cp -aL /dev/console $f
6191         echo $string > $f || error "echo $string to $f failed"
6192 }
6193 run_test 54e "console/tty device works in lustre ======================"
6194
6195 test_56a() {
6196         local numfiles=3
6197         local numdirs=2
6198         local dir=$DIR/$tdir
6199
6200         rm -rf $dir
6201         test_mkdir -p $dir/dir
6202         for i in $(seq $numfiles); do
6203                 touch $dir/file$i
6204                 touch $dir/dir/file$i
6205         done
6206
6207         local numcomp=$($LFS getstripe --component-count $dir)
6208
6209         [[ $numcomp == 0 ]] && numcomp=1
6210
6211         # test lfs getstripe with --recursive
6212         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6213
6214         [[ $filenum -eq $((numfiles * 2)) ]] ||
6215                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6216         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6217         [[ $filenum -eq $numfiles ]] ||
6218                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6219         echo "$LFS getstripe showed obdidx or l_ost_idx"
6220
6221         # test lfs getstripe with file instead of dir
6222         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6223         [[ $filenum -eq 1 ]] ||
6224                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6225         echo "$LFS getstripe file1 passed"
6226
6227         #test lfs getstripe with --verbose
6228         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6229         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6230                 error "$LFS getstripe --verbose $dir: "\
6231                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6232         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6233                 error "$LFS getstripe $dir: showed lmm_magic"
6234
6235         #test lfs getstripe with -v prints lmm_fid
6236         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6237         local countfids=$((numdirs + numfiles * numcomp))
6238         [[ $filenum -eq $countfids ]] ||
6239                 error "$LFS getstripe -v $dir: "\
6240                       "got $filenum want $countfids lmm_fid"
6241         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6242                 error "$LFS getstripe $dir: showed lmm_fid by default"
6243         echo "$LFS getstripe --verbose passed"
6244
6245         #check for FID information
6246         local fid1=$($LFS getstripe --fid $dir/file1)
6247         local fid2=$($LFS getstripe --verbose $dir/file1 |
6248                      awk '/lmm_fid: / { print $2; exit; }')
6249         local fid3=$($LFS path2fid $dir/file1)
6250
6251         [ "$fid1" != "$fid2" ] &&
6252                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6253         [ "$fid1" != "$fid3" ] &&
6254                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6255         echo "$LFS getstripe --fid passed"
6256
6257         #test lfs getstripe with --obd
6258         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6259                 error "$LFS getstripe --obd wrong_uuid: should return error"
6260
6261         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6262
6263         local ostidx=1
6264         local obduuid=$(ostuuid_from_index $ostidx)
6265         local found=$($LFS getstripe -r --obd $obduuid $dir |
6266                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6267
6268         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6269         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6270                 ((filenum--))
6271         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6272                 ((filenum--))
6273
6274         [[ $found -eq $filenum ]] ||
6275                 error "$LFS getstripe --obd: found $found expect $filenum"
6276         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6277                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6278                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6279                 error "$LFS getstripe --obd: should not show file on other obd"
6280         echo "$LFS getstripe --obd passed"
6281 }
6282 run_test 56a "check $LFS getstripe"
6283
6284 test_56b() {
6285         local dir=$DIR/$tdir
6286         local numdirs=3
6287
6288         test_mkdir $dir
6289         for i in $(seq $numdirs); do
6290                 test_mkdir $dir/dir$i
6291         done
6292
6293         # test lfs getdirstripe default mode is non-recursion, which is
6294         # different from lfs getstripe
6295         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6296
6297         [[ $dircnt -eq 1 ]] ||
6298                 error "$LFS getdirstripe: found $dircnt, not 1"
6299         dircnt=$($LFS getdirstripe --recursive $dir |
6300                 grep -c lmv_stripe_count)
6301         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6302                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6303 }
6304 run_test 56b "check $LFS getdirstripe"
6305
6306 test_56c() {
6307         remote_ost_nodsh && skip "remote OST with nodsh"
6308
6309         local ost_idx=0
6310         local ost_name=$(ostname_from_index $ost_idx)
6311         local old_status=$(ost_dev_status $ost_idx)
6312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6313
6314         [[ -z "$old_status" ]] ||
6315                 skip_env "OST $ost_name is in $old_status status"
6316
6317         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6318         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6319                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6320         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6321                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6322                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6323         fi
6324
6325         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6326                 error "$LFS df -v showing inactive devices"
6327         sleep_maxage
6328
6329         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6330
6331         [[ "$new_status" =~ "D" ]] ||
6332                 error "$ost_name status is '$new_status', missing 'D'"
6333         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6334                 [[ "$new_status" =~ "N" ]] ||
6335                         error "$ost_name status is '$new_status', missing 'N'"
6336         fi
6337         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6338                 [[ "$new_status" =~ "f" ]] ||
6339                         error "$ost_name status is '$new_status', missing 'f'"
6340         fi
6341
6342         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6343         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6344                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6345         [[ -z "$p" ]] && restore_lustre_params < $p || true
6346         sleep_maxage
6347
6348         new_status=$(ost_dev_status $ost_idx)
6349         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6350                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6351         # can't check 'f' as devices may actually be on flash
6352 }
6353 run_test 56c "check 'lfs df' showing device status"
6354
6355 test_56d() {
6356         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6357         local osts=$($LFS df -v $MOUNT | grep -c OST)
6358
6359         $LFS df $MOUNT
6360
6361         (( mdts == MDSCOUNT )) ||
6362                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6363         (( osts == OSTCOUNT )) ||
6364                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6365 }
6366 run_test 56d "'lfs df -v' prints only configured devices"
6367
6368 test_56e() {
6369         err_enoent=2 # No such file or directory
6370         err_eopnotsupp=95 # Operation not supported
6371
6372         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6373         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6374
6375         # Check for handling of path not exists
6376         output=$($LFS df $enoent_mnt 2>&1)
6377         ret=$?
6378
6379         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6380         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6381                 error "expect failure $err_enoent, not $ret"
6382
6383         # Check for handling of non-Lustre FS
6384         output=$($LFS df $notsup_mnt)
6385         ret=$?
6386
6387         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6388         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6389                 error "expect success $err_eopnotsupp, not $ret"
6390
6391         # Check for multiple LustreFS argument
6392         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6393         ret=$?
6394
6395         [[ $output -eq 3 && $ret -eq 0 ]] ||
6396                 error "expect success 3, not $output, rc = $ret"
6397
6398         # Check for correct non-Lustre FS handling among multiple
6399         # LustreFS argument
6400         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6401                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6402         ret=$?
6403
6404         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6405                 error "expect success 2, not $output, rc = $ret"
6406 }
6407 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6408
6409 NUMFILES=3
6410 NUMDIRS=3
6411 setup_56() {
6412         local local_tdir="$1"
6413         local local_numfiles="$2"
6414         local local_numdirs="$3"
6415         local dir_params="$4"
6416         local dir_stripe_params="$5"
6417
6418         if [ ! -d "$local_tdir" ] ; then
6419                 test_mkdir -p $dir_stripe_params $local_tdir
6420                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6421                 for i in $(seq $local_numfiles) ; do
6422                         touch $local_tdir/file$i
6423                 done
6424                 for i in $(seq $local_numdirs) ; do
6425                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6426                         for j in $(seq $local_numfiles) ; do
6427                                 touch $local_tdir/dir$i/file$j
6428                         done
6429                 done
6430         fi
6431 }
6432
6433 setup_56_special() {
6434         local local_tdir=$1
6435         local local_numfiles=$2
6436         local local_numdirs=$3
6437
6438         setup_56 $local_tdir $local_numfiles $local_numdirs
6439
6440         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6441                 for i in $(seq $local_numfiles) ; do
6442                         mknod $local_tdir/loop${i}b b 7 $i
6443                         mknod $local_tdir/null${i}c c 1 3
6444                         ln -s $local_tdir/file1 $local_tdir/link${i}
6445                 done
6446                 for i in $(seq $local_numdirs) ; do
6447                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6448                         mknod $local_tdir/dir$i/null${i}c c 1 3
6449                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6450                 done
6451         fi
6452 }
6453
6454 test_56g() {
6455         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6456         local expected=$(($NUMDIRS + 2))
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         # test lfs find with -name
6461         for i in $(seq $NUMFILES) ; do
6462                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6463
6464                 [ $nums -eq $expected ] ||
6465                         error "lfs find -name '*$i' $dir wrong: "\
6466                               "found $nums, expected $expected"
6467         done
6468 }
6469 run_test 56g "check lfs find -name"
6470
6471 test_56h() {
6472         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6473         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6474
6475         setup_56 $dir $NUMFILES $NUMDIRS
6476
6477         # test lfs find with ! -name
6478         for i in $(seq $NUMFILES) ; do
6479                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6480
6481                 [ $nums -eq $expected ] ||
6482                         error "lfs find ! -name '*$i' $dir wrong: "\
6483                               "found $nums, expected $expected"
6484         done
6485 }
6486 run_test 56h "check lfs find ! -name"
6487
6488 test_56i() {
6489         local dir=$DIR/$tdir
6490
6491         test_mkdir $dir
6492
6493         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6494         local out=$($cmd)
6495
6496         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6497 }
6498 run_test 56i "check 'lfs find -ost UUID' skips directories"
6499
6500 test_56j() {
6501         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6502
6503         setup_56_special $dir $NUMFILES $NUMDIRS
6504
6505         local expected=$((NUMDIRS + 1))
6506         local cmd="$LFS find -type d $dir"
6507         local nums=$($cmd | wc -l)
6508
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511 }
6512 run_test 56j "check lfs find -type d"
6513
6514 test_56k() {
6515         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6516
6517         setup_56_special $dir $NUMFILES $NUMDIRS
6518
6519         local expected=$(((NUMDIRS + 1) * NUMFILES))
6520         local cmd="$LFS find -type f $dir"
6521         local nums=$($cmd | wc -l)
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525 }
6526 run_test 56k "check lfs find -type f"
6527
6528 test_56l() {
6529         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6530
6531         setup_56_special $dir $NUMFILES $NUMDIRS
6532
6533         local expected=$((NUMDIRS + NUMFILES))
6534         local cmd="$LFS find -type b $dir"
6535         local nums=$($cmd | wc -l)
6536
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539 }
6540 run_test 56l "check lfs find -type b"
6541
6542 test_56m() {
6543         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6544
6545         setup_56_special $dir $NUMFILES $NUMDIRS
6546
6547         local expected=$((NUMDIRS + NUMFILES))
6548         local cmd="$LFS find -type c $dir"
6549         local nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552 }
6553 run_test 56m "check lfs find -type c"
6554
6555 test_56n() {
6556         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type l $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56n "check lfs find -type l"
6567
6568 test_56o() {
6569         local dir=$DIR/$tdir
6570
6571         setup_56 $dir $NUMFILES $NUMDIRS
6572         utime $dir/file1 > /dev/null || error "utime (1)"
6573         utime $dir/file2 > /dev/null || error "utime (2)"
6574         utime $dir/dir1 > /dev/null || error "utime (3)"
6575         utime $dir/dir2 > /dev/null || error "utime (4)"
6576         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6577         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6578
6579         local expected=4
6580         local nums=$($LFS find -mtime +0 $dir | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6584
6585         expected=12
6586         cmd="$LFS find -mtime 0 $dir"
6587         nums=$($cmd | wc -l)
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590 }
6591 run_test 56o "check lfs find -mtime for old files"
6592
6593 test_56ob() {
6594         local dir=$DIR/$tdir
6595         local expected=1
6596         local count=0
6597
6598         # just to make sure there is something that won't be found
6599         test_mkdir $dir
6600         touch $dir/$tfile.now
6601
6602         for age in year week day hour min; do
6603                 count=$((count + 1))
6604
6605                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6606                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6607                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6608
6609                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6610                 local nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613
6614                 cmd="$LFS find $dir -atime $count${age:0:1}"
6615                 nums=$($cmd | wc -l)
6616                 [ $nums -eq $expected ] ||
6617                         error "'$cmd' wrong: found $nums, expected $expected"
6618         done
6619
6620         sleep 2
6621         cmd="$LFS find $dir -ctime +1s -type f"
6622         nums=$($cmd | wc -l)
6623         (( $nums == $count * 2 + 1)) ||
6624                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6625 }
6626 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6627
6628 test_newerXY_base() {
6629         local x=$1
6630         local y=$2
6631         local dir=$DIR/$tdir
6632         local ref
6633         local negref
6634
6635         if [ $y == "t" ]; then
6636                 if [ $x == "b" ]; then
6637                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6638                 else
6639                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6640                 fi
6641         else
6642                 ref=$DIR/$tfile.newer.$x$y
6643                 touch $ref || error "touch $ref failed"
6644         fi
6645
6646         echo "before = $ref"
6647         sleep 2
6648         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6649         sleep 2
6650         if [ $y == "t" ]; then
6651                 if [ $x == "b" ]; then
6652                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6653                 else
6654                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6655                 fi
6656         else
6657                 negref=$DIR/$tfile.negnewer.$x$y
6658                 touch $negref || error "touch $negref failed"
6659         fi
6660
6661         echo "after = $negref"
6662         local cmd="$LFS find $dir -newer$x$y $ref"
6663         local nums=$(eval $cmd | wc -l)
6664         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6665
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6673
6674         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6675         nums=$(eval $cmd | wc -l)
6676         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6677                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6678
6679         rm -rf $DIR/*
6680 }
6681
6682 test_56oc() {
6683         test_newerXY_base "a" "a"
6684         test_newerXY_base "a" "m"
6685         test_newerXY_base "a" "c"
6686         test_newerXY_base "m" "a"
6687         test_newerXY_base "m" "m"
6688         test_newerXY_base "m" "c"
6689         test_newerXY_base "c" "a"
6690         test_newerXY_base "c" "m"
6691         test_newerXY_base "c" "c"
6692
6693         [[ -n "$sles_version" ]] &&
6694                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6695
6696         test_newerXY_base "a" "t"
6697         test_newerXY_base "m" "t"
6698         test_newerXY_base "c" "t"
6699
6700         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6701            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6702                 ! btime_supported && echo "btime unsupported" && return 0
6703
6704         test_newerXY_base "b" "b"
6705         test_newerXY_base "b" "t"
6706 }
6707 run_test 56oc "check lfs find -newerXY work"
6708
6709 btime_supported() {
6710         local dir=$DIR/$tdir
6711         local rc
6712
6713         mkdir -p $dir
6714         touch $dir/$tfile
6715         $LFS find $dir -btime -1d -type f
6716         rc=$?
6717         rm -rf $dir
6718         return $rc
6719 }
6720
6721 test_56od() {
6722         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6723                 ! btime_supported && skip "btime unsupported on MDS"
6724
6725         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6726                 ! btime_supported && skip "btime unsupported on clients"
6727
6728         local dir=$DIR/$tdir
6729         local ref=$DIR/$tfile.ref
6730         local negref=$DIR/$tfile.negref
6731
6732         mkdir $dir || error "mkdir $dir failed"
6733         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6734         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6735         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6736         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6737         touch $ref || error "touch $ref failed"
6738         # sleep 3 seconds at least
6739         sleep 3
6740
6741         local before=$(do_facet mds1 date +%s)
6742         local skew=$(($(date +%s) - before + 1))
6743
6744         if (( skew < 0 && skew > -5 )); then
6745                 sleep $((0 - skew + 1))
6746                 skew=0
6747         fi
6748
6749         # Set the dir stripe params to limit files all on MDT0,
6750         # otherwise we need to calc the max clock skew between
6751         # the client and MDTs.
6752         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6753         sleep 2
6754         touch $negref || error "touch $negref failed"
6755
6756         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6757         local nums=$($cmd | wc -l)
6758         local expected=$(((NUMFILES + 1) * NUMDIRS))
6759
6760         [ $nums -eq $expected ] ||
6761                 error "'$cmd' wrong: found $nums, expected $expected"
6762
6763         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6764         nums=$($cmd | wc -l)
6765         expected=$((NUMFILES + 1))
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768
6769         [ $skew -lt 0 ] && return
6770
6771         local after=$(do_facet mds1 date +%s)
6772         local age=$((after - before + 1 + skew))
6773
6774         cmd="$LFS find $dir -btime -${age}s -type f"
6775         nums=$($cmd | wc -l)
6776         expected=$(((NUMFILES + 1) * NUMDIRS))
6777
6778         echo "Clock skew between client and server: $skew, age:$age"
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781
6782         expected=$(($NUMDIRS + 1))
6783         cmd="$LFS find $dir -btime -${age}s -type d"
6784         nums=$($cmd | wc -l)
6785         [ $nums -eq $expected ] ||
6786                 error "'$cmd' wrong: found $nums, expected $expected"
6787         rm -f $ref $negref || error "Failed to remove $ref $negref"
6788 }
6789 run_test 56od "check lfs find -btime with units"
6790
6791 test_56p() {
6792         [ $RUNAS_ID -eq $UID ] &&
6793                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6794
6795         local dir=$DIR/$tdir
6796
6797         setup_56 $dir $NUMFILES $NUMDIRS
6798         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6799
6800         local expected=$NUMFILES
6801         local cmd="$LFS find -uid $RUNAS_ID $dir"
6802         local nums=$($cmd | wc -l)
6803
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6808         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56p "check lfs find -uid and ! -uid"
6814
6815 test_56q() {
6816         [ $RUNAS_ID -eq $UID ] &&
6817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6818
6819         local dir=$DIR/$tdir
6820
6821         setup_56 $dir $NUMFILES $NUMDIRS
6822         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6823
6824         local expected=$NUMFILES
6825         local cmd="$LFS find -gid $RUNAS_GID $dir"
6826         local nums=$($cmd | wc -l)
6827
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830
6831         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6832         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6833         nums=$($cmd | wc -l)
6834         [ $nums -eq $expected ] ||
6835                 error "'$cmd' wrong: found $nums, expected $expected"
6836 }
6837 run_test 56q "check lfs find -gid and ! -gid"
6838
6839 test_56r() {
6840         local dir=$DIR/$tdir
6841
6842         setup_56 $dir $NUMFILES $NUMDIRS
6843
6844         local expected=12
6845         local cmd="$LFS find -size 0 -type f -lazy $dir"
6846         local nums=$($cmd | wc -l)
6847
6848         [ $nums -eq $expected ] ||
6849                 error "'$cmd' wrong: found $nums, expected $expected"
6850         cmd="$LFS find -size 0 -type f $dir"
6851         nums=$($cmd | wc -l)
6852         [ $nums -eq $expected ] ||
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854
6855         expected=0
6856         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860         cmd="$LFS find ! -size 0 -type f $dir"
6861         nums=$($cmd | wc -l)
6862         [ $nums -eq $expected ] ||
6863                 error "'$cmd' wrong: found $nums, expected $expected"
6864
6865         echo "test" > $dir/$tfile
6866         echo "test2" > $dir/$tfile.2 && sync
6867         expected=1
6868         cmd="$LFS find -size 5 -type f -lazy $dir"
6869         nums=$($cmd | wc -l)
6870         [ $nums -eq $expected ] ||
6871                 error "'$cmd' wrong: found $nums, expected $expected"
6872         cmd="$LFS find -size 5 -type f $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876
6877         expected=1
6878         cmd="$LFS find -size +5 -type f -lazy $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882         cmd="$LFS find -size +5 -type f $dir"
6883         nums=$($cmd | wc -l)
6884         [ $nums -eq $expected ] ||
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886
6887         expected=2
6888         cmd="$LFS find -size +0 -type f -lazy $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892         cmd="$LFS find -size +0 -type f $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896
6897         expected=2
6898         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902         cmd="$LFS find ! -size -5 -type f $dir"
6903         nums=$($cmd | wc -l)
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906
6907         expected=12
6908         cmd="$LFS find -size -5 -type f -lazy $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912         cmd="$LFS find -size -5 -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916 }
6917 run_test 56r "check lfs find -size works"
6918
6919 test_56ra_sub() {
6920         local expected=$1
6921         local glimpses=$2
6922         local cmd="$3"
6923
6924         cancel_lru_locks $OSC
6925
6926         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6927         local nums=$($cmd | wc -l)
6928
6929         [ $nums -eq $expected ] ||
6930                 error "'$cmd' wrong: found $nums, expected $expected"
6931
6932         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6933
6934         if (( rpcs_before + glimpses != rpcs_after )); then
6935                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6936                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6937
6938                 if [[ $glimpses == 0 ]]; then
6939                         error "'$cmd' should not send glimpse RPCs to OST"
6940                 else
6941                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6942                 fi
6943         fi
6944 }
6945
6946 test_56ra() {
6947         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6948                 skip "MDS < 2.12.58 doesn't return LSOM data"
6949         local dir=$DIR/$tdir
6950         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6951
6952         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6953
6954         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6955         $LCTL set_param -n llite.*.statahead_agl=0
6956         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6957
6958         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6959         # open and close all files to ensure LSOM is updated
6960         cancel_lru_locks $OSC
6961         find $dir -type f | xargs cat > /dev/null
6962
6963         #   expect_found  glimpse_rpcs  command_to_run
6964         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6965         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6966         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6967         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6968
6969         echo "test" > $dir/$tfile
6970         echo "test2" > $dir/$tfile.2 && sync
6971         cancel_lru_locks $OSC
6972         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6973
6974         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6975         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6976         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6977         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6978
6979         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6980         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6981         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6982         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6983         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6984         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6985 }
6986 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6987
6988 test_56rb() {
6989         local dir=$DIR/$tdir
6990         local tmp=$TMP/$tfile.log
6991         local mdt_idx;
6992
6993         test_mkdir -p $dir || error "failed to mkdir $dir"
6994         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6995                 error "failed to setstripe $dir/$tfile"
6996         mdt_idx=$($LFS getdirstripe -i $dir)
6997         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6998
6999         stack_trap "rm -f $tmp" EXIT
7000         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7001         ! grep -q obd_uuid $tmp ||
7002                 error "failed to find --size +100K --ost 0 $dir"
7003         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7004         ! grep -q obd_uuid $tmp ||
7005                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7006 }
7007 run_test 56rb "check lfs find --size --ost/--mdt works"
7008
7009 test_56rc() {
7010         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7011         local dir=$DIR/$tdir
7012         local found
7013
7014         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7015         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7016         (( $MDSCOUNT > 2 )) &&
7017                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7018         mkdir $dir/$tdir-{1..10}
7019         touch $dir/$tfile-{1..10}
7020
7021         found=$($LFS find $dir --mdt-count 2 | wc -l)
7022         expect=11
7023         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7024
7025         found=$($LFS find $dir -T +1 | wc -l)
7026         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7027         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7028
7029         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7030         expect=11
7031         (( $found == $expect )) || error "found $found all_char, expect $expect"
7032
7033         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7034         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7035         (( $found == $expect )) || error "found $found all_char, expect $expect"
7036 }
7037 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7038
7039 test_56s() { # LU-611 #LU-9369
7040         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7041
7042         local dir=$DIR/$tdir
7043         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7044
7045         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7046         for i in $(seq $NUMDIRS); do
7047                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7048         done
7049
7050         local expected=$NUMDIRS
7051         local cmd="$LFS find -c $OSTCOUNT $dir"
7052         local nums=$($cmd | wc -l)
7053
7054         [ $nums -eq $expected ] || {
7055                 $LFS getstripe -R $dir
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057         }
7058
7059         expected=$((NUMDIRS + onestripe))
7060         cmd="$LFS find -stripe-count +0 -type f $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] || {
7063                 $LFS getstripe -R $dir
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065         }
7066
7067         expected=$onestripe
7068         cmd="$LFS find -stripe-count 1 -type f $dir"
7069         nums=$($cmd | wc -l)
7070         [ $nums -eq $expected ] || {
7071                 $LFS getstripe -R $dir
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073         }
7074
7075         cmd="$LFS find -stripe-count -2 -type f $dir"
7076         nums=$($cmd | wc -l)
7077         [ $nums -eq $expected ] || {
7078                 $LFS getstripe -R $dir
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         }
7081
7082         expected=0
7083         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7084         nums=$($cmd | wc -l)
7085         [ $nums -eq $expected ] || {
7086                 $LFS getstripe -R $dir
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         }
7089 }
7090 run_test 56s "check lfs find -stripe-count works"
7091
7092 test_56t() { # LU-611 #LU-9369
7093         local dir=$DIR/$tdir
7094
7095         setup_56 $dir 0 $NUMDIRS
7096         for i in $(seq $NUMDIRS); do
7097                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7098         done
7099
7100         local expected=$NUMDIRS
7101         local cmd="$LFS find -S 8M $dir"
7102         local nums=$($cmd | wc -l)
7103
7104         [ $nums -eq $expected ] || {
7105                 $LFS getstripe -R $dir
7106                 error "'$cmd' wrong: found $nums, expected $expected"
7107         }
7108         rm -rf $dir
7109
7110         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7111
7112         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7113
7114         expected=$(((NUMDIRS + 1) * NUMFILES))
7115         cmd="$LFS find -stripe-size 512k -type f $dir"
7116         nums=$($cmd | wc -l)
7117         [ $nums -eq $expected ] ||
7118                 error "'$cmd' wrong: found $nums, expected $expected"
7119
7120         cmd="$LFS find -stripe-size +320k -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7126         cmd="$LFS find -stripe-size +200k -type f $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130
7131         cmd="$LFS find -stripe-size -640k -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         expected=4
7137         cmd="$LFS find -stripe-size 256k -type f $dir"
7138         nums=$($cmd | wc -l)
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141
7142         cmd="$LFS find -stripe-size -320k -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146
7147         expected=0
7148         cmd="$LFS find -stripe-size 1024k -type f $dir"
7149         nums=$($cmd | wc -l)
7150         [ $nums -eq $expected ] ||
7151                 error "'$cmd' wrong: found $nums, expected $expected"
7152 }
7153 run_test 56t "check lfs find -stripe-size works"
7154
7155 test_56u() { # LU-611
7156         local dir=$DIR/$tdir
7157
7158         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7159
7160         if [[ $OSTCOUNT -gt 1 ]]; then
7161                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7162                 onestripe=4
7163         else
7164                 onestripe=0
7165         fi
7166
7167         local expected=$(((NUMDIRS + 1) * NUMFILES))
7168         local cmd="$LFS find -stripe-index 0 -type f $dir"
7169         local nums=$($cmd | wc -l)
7170
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173
7174         expected=$onestripe
7175         cmd="$LFS find -stripe-index 1 -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7181         nums=$($cmd | wc -l)
7182         [ $nums -eq $expected ] ||
7183                 error "'$cmd' wrong: found $nums, expected $expected"
7184
7185         expected=0
7186         # This should produce an error and not return any files
7187         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7188         nums=$($cmd 2>/dev/null | wc -l)
7189         [ $nums -eq $expected ] ||
7190                 error "'$cmd' wrong: found $nums, expected $expected"
7191
7192         if [[ $OSTCOUNT -gt 1 ]]; then
7193                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7194                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7195                 nums=$($cmd | wc -l)
7196                 [ $nums -eq $expected ] ||
7197                         error "'$cmd' wrong: found $nums, expected $expected"
7198         fi
7199 }
7200 run_test 56u "check lfs find -stripe-index works"
7201
7202 test_56v() {
7203         local mdt_idx=0
7204         local dir=$DIR/$tdir
7205
7206         setup_56 $dir $NUMFILES $NUMDIRS
7207
7208         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7209         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7210
7211         for file in $($LFS find -m $UUID $dir); do
7212                 file_midx=$($LFS getstripe -m $file)
7213                 [ $file_midx -eq $mdt_idx ] ||
7214                         error "lfs find -m $UUID != getstripe -m $file_midx"
7215         done
7216 }
7217 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7218
7219 test_56w() {
7220         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7222
7223         local dir=$DIR/$tdir
7224
7225         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7226
7227         local stripe_size=$($LFS getstripe -S -d $dir) ||
7228                 error "$LFS getstripe -S -d $dir failed"
7229         stripe_size=${stripe_size%% *}
7230
7231         local file_size=$((stripe_size * OSTCOUNT))
7232         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7233         local required_space=$((file_num * file_size))
7234         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7235                            head -n1)
7236         [[ $free_space -le $((required_space / 1024)) ]] &&
7237                 skip_env "need $required_space, have $free_space kbytes"
7238
7239         local dd_bs=65536
7240         local dd_count=$((file_size / dd_bs))
7241
7242         # write data into the files
7243         local i
7244         local j
7245         local file
7246
7247         for i in $(seq $NUMFILES); do
7248                 file=$dir/file$i
7249                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7250                         error "write data into $file failed"
7251         done
7252         for i in $(seq $NUMDIRS); do
7253                 for j in $(seq $NUMFILES); do
7254                         file=$dir/dir$i/file$j
7255                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7256                                 error "write data into $file failed"
7257                 done
7258         done
7259
7260         # $LFS_MIGRATE will fail if hard link migration is unsupported
7261         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7262                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7263                         error "creating links to $dir/dir1/file1 failed"
7264         fi
7265
7266         local expected=-1
7267
7268         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7269
7270         # lfs_migrate file
7271         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7272
7273         echo "$cmd"
7274         eval $cmd || error "$cmd failed"
7275
7276         check_stripe_count $dir/file1 $expected
7277
7278         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7279         then
7280                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7281                 # OST 1 if it is on OST 0. This file is small enough to
7282                 # be on only one stripe.
7283                 file=$dir/migr_1_ost
7284                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7285                         error "write data into $file failed"
7286                 local obdidx=$($LFS getstripe -i $file)
7287                 local oldmd5=$(md5sum $file)
7288                 local newobdidx=0
7289
7290                 [[ $obdidx -eq 0 ]] && newobdidx=1
7291                 cmd="$LFS migrate -i $newobdidx $file"
7292                 echo $cmd
7293                 eval $cmd || error "$cmd failed"
7294
7295                 local realobdix=$($LFS getstripe -i $file)
7296                 local newmd5=$(md5sum $file)
7297
7298                 [[ $newobdidx -ne $realobdix ]] &&
7299                         error "new OST is different (was=$obdidx, "\
7300                               "wanted=$newobdidx, got=$realobdix)"
7301                 [[ "$oldmd5" != "$newmd5" ]] &&
7302                         error "md5sum differ: $oldmd5, $newmd5"
7303         fi
7304
7305         # lfs_migrate dir
7306         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7307         echo "$cmd"
7308         eval $cmd || error "$cmd failed"
7309
7310         for j in $(seq $NUMFILES); do
7311                 check_stripe_count $dir/dir1/file$j $expected
7312         done
7313
7314         # lfs_migrate works with lfs find
7315         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7316              $LFS_MIGRATE -y -c $expected"
7317         echo "$cmd"
7318         eval $cmd || error "$cmd failed"
7319
7320         for i in $(seq 2 $NUMFILES); do
7321                 check_stripe_count $dir/file$i $expected
7322         done
7323         for i in $(seq 2 $NUMDIRS); do
7324                 for j in $(seq $NUMFILES); do
7325                 check_stripe_count $dir/dir$i/file$j $expected
7326                 done
7327         done
7328 }
7329 run_test 56w "check lfs_migrate -c stripe_count works"
7330
7331 test_56wb() {
7332         local file1=$DIR/$tdir/file1
7333         local create_pool=false
7334         local initial_pool=$($LFS getstripe -p $DIR)
7335         local pool_list=()
7336         local pool=""
7337
7338         echo -n "Creating test dir..."
7339         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7340         echo "done."
7341
7342         echo -n "Creating test file..."
7343         touch $file1 || error "cannot create file"
7344         echo "done."
7345
7346         echo -n "Detecting existing pools..."
7347         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7348
7349         if [ ${#pool_list[@]} -gt 0 ]; then
7350                 echo "${pool_list[@]}"
7351                 for thispool in "${pool_list[@]}"; do
7352                         if [[ -z "$initial_pool" ||
7353                               "$initial_pool" != "$thispool" ]]; then
7354                                 pool="$thispool"
7355                                 echo "Using existing pool '$pool'"
7356                                 break
7357                         fi
7358                 done
7359         else
7360                 echo "none detected."
7361         fi
7362         if [ -z "$pool" ]; then
7363                 pool=${POOL:-testpool}
7364                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7365                 echo -n "Creating pool '$pool'..."
7366                 create_pool=true
7367                 pool_add $pool &> /dev/null ||
7368                         error "pool_add failed"
7369                 echo "done."
7370
7371                 echo -n "Adding target to pool..."
7372                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7373                         error "pool_add_targets failed"
7374                 echo "done."
7375         fi
7376
7377         echo -n "Setting pool using -p option..."
7378         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7379                 error "migrate failed rc = $?"
7380         echo "done."
7381
7382         echo -n "Verifying test file is in pool after migrating..."
7383         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7384                 error "file was not migrated to pool $pool"
7385         echo "done."
7386
7387         echo -n "Removing test file from pool '$pool'..."
7388         # "lfs migrate $file" won't remove the file from the pool
7389         # until some striping information is changed.
7390         $LFS migrate -c 1 $file1 &> /dev/null ||
7391                 error "cannot remove from pool"
7392         [ "$($LFS getstripe -p $file1)" ] &&
7393                 error "pool still set"
7394         echo "done."
7395
7396         echo -n "Setting pool using --pool option..."
7397         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7398                 error "migrate failed rc = $?"
7399         echo "done."
7400
7401         # Clean up
7402         rm -f $file1
7403         if $create_pool; then
7404                 destroy_test_pools 2> /dev/null ||
7405                         error "destroy test pools failed"
7406         fi
7407 }
7408 run_test 56wb "check lfs_migrate pool support"
7409
7410 test_56wc() {
7411         local file1="$DIR/$tdir/file1"
7412         local parent_ssize
7413         local parent_scount
7414         local cur_ssize
7415         local cur_scount
7416         local orig_ssize
7417
7418         echo -n "Creating test dir..."
7419         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7420         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7421                 error "cannot set stripe by '-S 1M -c 1'"
7422         echo "done"
7423
7424         echo -n "Setting initial stripe for test file..."
7425         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7426                 error "cannot set stripe"
7427         cur_ssize=$($LFS getstripe -S "$file1")
7428         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7429         echo "done."
7430
7431         # File currently set to -S 512K -c 1
7432
7433         # Ensure -c and -S options are rejected when -R is set
7434         echo -n "Verifying incompatible options are detected..."
7435         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7436                 error "incompatible -c and -R options not detected"
7437         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7438                 error "incompatible -S and -R options not detected"
7439         echo "done."
7440
7441         # Ensure unrecognized options are passed through to 'lfs migrate'
7442         echo -n "Verifying -S option is passed through to lfs migrate..."
7443         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7444                 error "migration failed"
7445         cur_ssize=$($LFS getstripe -S "$file1")
7446         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7447         echo "done."
7448
7449         # File currently set to -S 1M -c 1
7450
7451         # Ensure long options are supported
7452         echo -n "Verifying long options supported..."
7453         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7454                 error "long option without argument not supported"
7455         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7456                 error "long option with argument not supported"
7457         cur_ssize=$($LFS getstripe -S "$file1")
7458         [ $cur_ssize -eq 524288 ] ||
7459                 error "migrate --stripe-size $cur_ssize != 524288"
7460         echo "done."
7461
7462         # File currently set to -S 512K -c 1
7463
7464         if [ "$OSTCOUNT" -gt 1 ]; then
7465                 echo -n "Verifying explicit stripe count can be set..."
7466                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7467                         error "migrate failed"
7468                 cur_scount=$($LFS getstripe -c "$file1")
7469                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7470                 echo "done."
7471         fi
7472
7473         # File currently set to -S 512K -c 1 or -S 512K -c 2
7474
7475         # Ensure parent striping is used if -R is set, and no stripe
7476         # count or size is specified
7477         echo -n "Setting stripe for parent directory..."
7478         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7479                 error "cannot set stripe '-S 2M -c 1'"
7480         echo "done."
7481
7482         echo -n "Verifying restripe option uses parent stripe settings..."
7483         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7484         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7485         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7486                 error "migrate failed"
7487         cur_ssize=$($LFS getstripe -S "$file1")
7488         [ $cur_ssize -eq $parent_ssize ] ||
7489                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7490         cur_scount=$($LFS getstripe -c "$file1")
7491         [ $cur_scount -eq $parent_scount ] ||
7492                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7493         echo "done."
7494
7495         # File currently set to -S 1M -c 1
7496
7497         # Ensure striping is preserved if -R is not set, and no stripe
7498         # count or size is specified
7499         echo -n "Verifying striping size preserved when not specified..."
7500         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7501         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7502                 error "cannot set stripe on parent directory"
7503         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7504                 error "migrate failed"
7505         cur_ssize=$($LFS getstripe -S "$file1")
7506         [ $cur_ssize -eq $orig_ssize ] ||
7507                 error "migrate by default $cur_ssize != $orig_ssize"
7508         echo "done."
7509
7510         # Ensure file name properly detected when final option has no argument
7511         echo -n "Verifying file name properly detected..."
7512         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7513                 error "file name interpreted as option argument"
7514         echo "done."
7515
7516         # Clean up
7517         rm -f "$file1"
7518 }
7519 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7520
7521 test_56wd() {
7522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7523
7524         local file1=$DIR/$tdir/file1
7525
7526         echo -n "Creating test dir..."
7527         test_mkdir $DIR/$tdir || error "cannot create dir"
7528         echo "done."
7529
7530         echo -n "Creating test file..."
7531         touch $file1
7532         echo "done."
7533
7534         # Ensure 'lfs migrate' will fail by using a non-existent option,
7535         # and make sure rsync is not called to recover
7536         echo -n "Make sure --no-rsync option works..."
7537         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7538                 grep -q 'refusing to fall back to rsync' ||
7539                 error "rsync was called with --no-rsync set"
7540         echo "done."
7541
7542         # Ensure rsync is called without trying 'lfs migrate' first
7543         echo -n "Make sure --rsync option works..."
7544         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7545                 grep -q 'falling back to rsync' &&
7546                 error "lfs migrate was called with --rsync set"
7547         echo "done."
7548
7549         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7550         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7551                 grep -q 'at the same time' ||
7552                 error "--rsync and --no-rsync accepted concurrently"
7553         echo "done."
7554
7555         # Clean up
7556         rm -f $file1
7557 }
7558 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7559
7560 test_56we() {
7561         local td=$DIR/$tdir
7562         local tf=$td/$tfile
7563
7564         test_mkdir $td || error "cannot create $td"
7565         touch $tf || error "cannot touch $tf"
7566
7567         echo -n "Make sure --non-direct|-D works..."
7568         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7569                 grep -q "lfs migrate --non-direct" ||
7570                 error "--non-direct option cannot work correctly"
7571         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7572                 grep -q "lfs migrate -D" ||
7573                 error "-D option cannot work correctly"
7574         echo "done."
7575 }
7576 run_test 56we "check lfs_migrate --non-direct|-D support"
7577
7578 test_56x() {
7579         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7580         check_swap_layouts_support
7581
7582         local dir=$DIR/$tdir
7583         local ref1=/etc/passwd
7584         local file1=$dir/file1
7585
7586         test_mkdir $dir || error "creating dir $dir"
7587         $LFS setstripe -c 2 $file1
7588         cp $ref1 $file1
7589         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7590         stripe=$($LFS getstripe -c $file1)
7591         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7592         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7593
7594         # clean up
7595         rm -f $file1
7596 }
7597 run_test 56x "lfs migration support"
7598
7599 test_56xa() {
7600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7601         check_swap_layouts_support
7602
7603         local dir=$DIR/$tdir/$testnum
7604
7605         test_mkdir -p $dir
7606
7607         local ref1=/etc/passwd
7608         local file1=$dir/file1
7609
7610         $LFS setstripe -c 2 $file1
7611         cp $ref1 $file1
7612         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7613
7614         local stripe=$($LFS getstripe -c $file1)
7615
7616         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7617         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7618
7619         # clean up
7620         rm -f $file1
7621 }
7622 run_test 56xa "lfs migration --block support"
7623
7624 check_migrate_links() {
7625         local dir="$1"
7626         local file1="$dir/file1"
7627         local begin="$2"
7628         local count="$3"
7629         local runas="$4"
7630         local total_count=$(($begin + $count - 1))
7631         local symlink_count=10
7632         local uniq_count=10
7633
7634         if [ ! -f "$file1" ]; then
7635                 echo -n "creating initial file..."
7636                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7637                         error "cannot setstripe initial file"
7638                 echo "done"
7639
7640                 echo -n "creating symlinks..."
7641                 for s in $(seq 1 $symlink_count); do
7642                         ln -s "$file1" "$dir/slink$s" ||
7643                                 error "cannot create symlinks"
7644                 done
7645                 echo "done"
7646
7647                 echo -n "creating nonlinked files..."
7648                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7649                         error "cannot create nonlinked files"
7650                 echo "done"
7651         fi
7652
7653         # create hard links
7654         if [ ! -f "$dir/file$total_count" ]; then
7655                 echo -n "creating hard links $begin:$total_count..."
7656                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7657                         /dev/null || error "cannot create hard links"
7658                 echo "done"
7659         fi
7660
7661         echo -n "checking number of hard links listed in xattrs..."
7662         local fid=$($LFS getstripe -F "$file1")
7663         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7664
7665         echo "${#paths[*]}"
7666         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7667                         skip "hard link list has unexpected size, skipping test"
7668         fi
7669         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7670                         error "link names should exceed xattrs size"
7671         fi
7672
7673         echo -n "migrating files..."
7674         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7675         local rc=$?
7676         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7677         echo "done"
7678
7679         # make sure all links have been properly migrated
7680         echo -n "verifying files..."
7681         fid=$($LFS getstripe -F "$file1") ||
7682                 error "cannot get fid for file $file1"
7683         for i in $(seq 2 $total_count); do
7684                 local fid2=$($LFS getstripe -F $dir/file$i)
7685
7686                 [ "$fid2" == "$fid" ] ||
7687                         error "migrated hard link has mismatched FID"
7688         done
7689
7690         # make sure hard links were properly detected, and migration was
7691         # performed only once for the entire link set; nonlinked files should
7692         # also be migrated
7693         local actual=$(grep -c 'done' <<< "$migrate_out")
7694         local expected=$(($uniq_count + 1))
7695
7696         [ "$actual" -eq  "$expected" ] ||
7697                 error "hard links individually migrated ($actual != $expected)"
7698
7699         # make sure the correct number of hard links are present
7700         local hardlinks=$(stat -c '%h' "$file1")
7701
7702         [ $hardlinks -eq $total_count ] ||
7703                 error "num hard links $hardlinks != $total_count"
7704         echo "done"
7705
7706         return 0
7707 }
7708
7709 test_56xb() {
7710         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7711                 skip "Need MDS version at least 2.10.55"
7712
7713         local dir="$DIR/$tdir"
7714
7715         test_mkdir "$dir" || error "cannot create dir $dir"
7716
7717         echo "testing lfs migrate mode when all links fit within xattrs"
7718         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7719
7720         echo "testing rsync mode when all links fit within xattrs"
7721         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7722
7723         echo "testing lfs migrate mode when all links do not fit within xattrs"
7724         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7725
7726         echo "testing rsync mode when all links do not fit within xattrs"
7727         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7728
7729         chown -R $RUNAS_ID $dir
7730         echo "testing non-root lfs migrate mode when not all links are in xattr"
7731         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7732
7733         # clean up
7734         rm -rf $dir
7735 }
7736 run_test 56xb "lfs migration hard link support"
7737
7738 test_56xc() {
7739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7740
7741         local dir="$DIR/$tdir"
7742
7743         test_mkdir "$dir" || error "cannot create dir $dir"
7744
7745         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7746         echo -n "Setting initial stripe for 20MB test file..."
7747         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7748                 error "cannot setstripe 20MB file"
7749         echo "done"
7750         echo -n "Sizing 20MB test file..."
7751         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7752         echo "done"
7753         echo -n "Verifying small file autostripe count is 1..."
7754         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7755                 error "cannot migrate 20MB file"
7756         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7757                 error "cannot get stripe for $dir/20mb"
7758         [ $stripe_count -eq 1 ] ||
7759                 error "unexpected stripe count $stripe_count for 20MB file"
7760         rm -f "$dir/20mb"
7761         echo "done"
7762
7763         # Test 2: File is small enough to fit within the available space on
7764         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7765         # have at least an additional 1KB for each desired stripe for test 3
7766         echo -n "Setting stripe for 1GB test file..."
7767         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7768         echo "done"
7769         echo -n "Sizing 1GB test file..."
7770         # File size is 1GB + 3KB
7771         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7772         echo "done"
7773
7774         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7775         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7776         if (( avail > 524288 * OSTCOUNT )); then
7777                 echo -n "Migrating 1GB file..."
7778                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7779                         error "cannot migrate 1GB file"
7780                 echo "done"
7781                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7782                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7783                         error "cannot getstripe for 1GB file"
7784                 [ $stripe_count -eq 2 ] ||
7785                         error "unexpected stripe count $stripe_count != 2"
7786                 echo "done"
7787         fi
7788
7789         # Test 3: File is too large to fit within the available space on
7790         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7791         if [ $OSTCOUNT -ge 3 ]; then
7792                 # The required available space is calculated as
7793                 # file size (1GB + 3KB) / OST count (3).
7794                 local kb_per_ost=349526
7795
7796                 echo -n "Migrating 1GB file with limit..."
7797                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7798                         error "cannot migrate 1GB file with limit"
7799                 echo "done"
7800
7801                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7802                 echo -n "Verifying 1GB autostripe count with limited space..."
7803                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7804                         error "unexpected stripe count $stripe_count (min 3)"
7805                 echo "done"
7806         fi
7807
7808         # clean up
7809         rm -rf $dir
7810 }
7811 run_test 56xc "lfs migration autostripe"
7812
7813 test_56xd() {
7814         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7815
7816         local dir=$DIR/$tdir
7817         local f_mgrt=$dir/$tfile.mgrt
7818         local f_yaml=$dir/$tfile.yaml
7819         local f_copy=$dir/$tfile.copy
7820         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7821         local layout_copy="-c 2 -S 2M -i 1"
7822         local yamlfile=$dir/yamlfile
7823         local layout_before;
7824         local layout_after;
7825
7826         test_mkdir "$dir" || error "cannot create dir $dir"
7827         $LFS setstripe $layout_yaml $f_yaml ||
7828                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7829         $LFS getstripe --yaml $f_yaml > $yamlfile
7830         $LFS setstripe $layout_copy $f_copy ||
7831                 error "cannot setstripe $f_copy with layout $layout_copy"
7832         touch $f_mgrt
7833         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7834
7835         # 1. test option --yaml
7836         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7837                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7838         layout_before=$(get_layout_param $f_yaml)
7839         layout_after=$(get_layout_param $f_mgrt)
7840         [ "$layout_after" == "$layout_before" ] ||
7841                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7842
7843         # 2. test option --copy
7844         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7845                 error "cannot migrate $f_mgrt with --copy $f_copy"
7846         layout_before=$(get_layout_param $f_copy)
7847         layout_after=$(get_layout_param $f_mgrt)
7848         [ "$layout_after" == "$layout_before" ] ||
7849                 error "lfs_migrate --copy: $layout_after != $layout_before"
7850 }
7851 run_test 56xd "check lfs_migrate --yaml and --copy support"
7852
7853 test_56xe() {
7854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7855
7856         local dir=$DIR/$tdir
7857         local f_comp=$dir/$tfile
7858         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7859         local layout_before=""
7860         local layout_after=""
7861
7862         test_mkdir "$dir" || error "cannot create dir $dir"
7863         $LFS setstripe $layout $f_comp ||
7864                 error "cannot setstripe $f_comp with layout $layout"
7865         layout_before=$(get_layout_param $f_comp)
7866         dd if=/dev/zero of=$f_comp bs=1M count=4
7867
7868         # 1. migrate a comp layout file by lfs_migrate
7869         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7870         layout_after=$(get_layout_param $f_comp)
7871         [ "$layout_before" == "$layout_after" ] ||
7872                 error "lfs_migrate: $layout_before != $layout_after"
7873
7874         # 2. migrate a comp layout file by lfs migrate
7875         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7876         layout_after=$(get_layout_param $f_comp)
7877         [ "$layout_before" == "$layout_after" ] ||
7878                 error "lfs migrate: $layout_before != $layout_after"
7879 }
7880 run_test 56xe "migrate a composite layout file"
7881
7882 test_56xf() {
7883         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7884
7885         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7886                 skip "Need server version at least 2.13.53"
7887
7888         local dir=$DIR/$tdir
7889         local f_comp=$dir/$tfile
7890         local layout="-E 1M -c1 -E -1 -c2"
7891         local fid_before=""
7892         local fid_after=""
7893
7894         test_mkdir "$dir" || error "cannot create dir $dir"
7895         $LFS setstripe $layout $f_comp ||
7896                 error "cannot setstripe $f_comp with layout $layout"
7897         fid_before=$($LFS getstripe --fid $f_comp)
7898         dd if=/dev/zero of=$f_comp bs=1M count=4
7899
7900         # 1. migrate a comp layout file to a comp layout
7901         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7902         fid_after=$($LFS getstripe --fid $f_comp)
7903         [ "$fid_before" == "$fid_after" ] ||
7904                 error "comp-to-comp migrate: $fid_before != $fid_after"
7905
7906         # 2. migrate a comp layout file to a plain layout
7907         $LFS migrate -c2 $f_comp ||
7908                 error "cannot migrate $f_comp by lfs migrate"
7909         fid_after=$($LFS getstripe --fid $f_comp)
7910         [ "$fid_before" == "$fid_after" ] ||
7911                 error "comp-to-plain migrate: $fid_before != $fid_after"
7912
7913         # 3. migrate a plain layout file to a comp layout
7914         $LFS migrate $layout $f_comp ||
7915                 error "cannot migrate $f_comp by lfs migrate"
7916         fid_after=$($LFS getstripe --fid $f_comp)
7917         [ "$fid_before" == "$fid_after" ] ||
7918                 error "plain-to-comp migrate: $fid_before != $fid_after"
7919 }
7920 run_test 56xf "FID is not lost during migration of a composite layout file"
7921
7922 check_file_ost_range() {
7923         local file="$1"
7924         shift
7925         local range="$*"
7926         local -a file_range
7927         local idx
7928
7929         file_range=($($LFS getstripe -y "$file" |
7930                 awk '/l_ost_idx:/ { print $NF }'))
7931
7932         if [[ "${#file_range[@]}" = 0 ]]; then
7933                 echo "No osts found for $file"
7934                 return 1
7935         fi
7936
7937         for idx in "${file_range[@]}"; do
7938                 [[ " $range " =~ " $idx " ]] ||
7939                         return 1
7940         done
7941
7942         return 0
7943 }
7944
7945 sub_test_56xg() {
7946         local stripe_opt="$1"
7947         local pool="$2"
7948         shift 2
7949         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7950
7951         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7952                 error "Fail to migrate $tfile on $pool"
7953         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7954                 error "$tfile is not in pool $pool"
7955         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7956                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7957 }
7958
7959 test_56xg() {
7960         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7961         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7962         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7963                 skip "Need MDS version newer than 2.14.52"
7964
7965         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7966         local -a pool_ranges=("0 0" "1 1" "0 1")
7967
7968         # init pools
7969         for i in "${!pool_names[@]}"; do
7970                 pool_add ${pool_names[$i]} ||
7971                         error "pool_add failed (pool: ${pool_names[$i]})"
7972                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7973                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7974         done
7975
7976         # init the file to migrate
7977         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7978                 error "Unable to create $tfile on OST1"
7979         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7980                 error "Unable to write on $tfile"
7981
7982         echo "1. migrate $tfile on pool ${pool_names[0]}"
7983         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7984
7985         echo "2. migrate $tfile on pool ${pool_names[2]}"
7986         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7987
7988         echo "3. migrate $tfile on pool ${pool_names[1]}"
7989         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7990
7991         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7992         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7993         echo
7994
7995         # Clean pools
7996         destroy_test_pools ||
7997                 error "pool_destroy failed"
7998 }
7999 run_test 56xg "lfs migrate pool support"
8000
8001 test_56y() {
8002         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8003                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8004
8005         local res=""
8006         local dir=$DIR/$tdir
8007         local f1=$dir/file1
8008         local f2=$dir/file2
8009
8010         test_mkdir -p $dir || error "creating dir $dir"
8011         touch $f1 || error "creating std file $f1"
8012         $MULTIOP $f2 H2c || error "creating released file $f2"
8013
8014         # a directory can be raid0, so ask only for files
8015         res=$($LFS find $dir -L raid0 -type f | wc -l)
8016         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8017
8018         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8019         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8020
8021         # only files can be released, so no need to force file search
8022         res=$($LFS find $dir -L released)
8023         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8024
8025         res=$($LFS find $dir -type f \! -L released)
8026         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8027 }
8028 run_test 56y "lfs find -L raid0|released"
8029
8030 test_56z() { # LU-4824
8031         # This checks to make sure 'lfs find' continues after errors
8032         # There are two classes of errors that should be caught:
8033         # - If multiple paths are provided, all should be searched even if one
8034         #   errors out
8035         # - If errors are encountered during the search, it should not terminate
8036         #   early
8037         local dir=$DIR/$tdir
8038         local i
8039
8040         test_mkdir $dir
8041         for i in d{0..9}; do
8042                 test_mkdir $dir/$i
8043                 touch $dir/$i/$tfile
8044         done
8045         $LFS find $DIR/non_existent_dir $dir &&
8046                 error "$LFS find did not return an error"
8047         # Make a directory unsearchable. This should NOT be the last entry in
8048         # directory order.  Arbitrarily pick the 6th entry
8049         chmod 700 $($LFS find $dir -type d | sed '6!d')
8050
8051         $RUNAS $LFS find $DIR/non_existent $dir
8052         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8053
8054         # The user should be able to see 10 directories and 9 files
8055         (( count == 19 )) ||
8056                 error "$LFS find found $count != 19 entries after error"
8057 }
8058 run_test 56z "lfs find should continue after an error"
8059
8060 test_56aa() { # LU-5937
8061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8062
8063         local dir=$DIR/$tdir
8064
8065         mkdir $dir
8066         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8067
8068         createmany -o $dir/striped_dir/${tfile}- 1024
8069         local dirs=$($LFS find --size +8k $dir/)
8070
8071         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8072 }
8073 run_test 56aa "lfs find --size under striped dir"
8074
8075 test_56ab() { # LU-10705
8076         test_mkdir $DIR/$tdir
8077         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8078         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8079         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8080         # Flush writes to ensure valid blocks.  Need to be more thorough for
8081         # ZFS, since blocks are not allocated/returned to client immediately.
8082         sync_all_data
8083         wait_zfs_commit ost1 2
8084         cancel_lru_locks osc
8085         ls -ls $DIR/$tdir
8086
8087         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8088
8089         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8090
8091         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8092         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8093
8094         rm -f $DIR/$tdir/$tfile.[123]
8095 }
8096 run_test 56ab "lfs find --blocks"
8097
8098 # LU-11188
8099 test_56aca() {
8100         local dir="$DIR/$tdir"
8101         local perms=(001 002 003 004 005 006 007
8102                      010 020 030 040 050 060 070
8103                      100 200 300 400 500 600 700
8104                      111 222 333 444 555 666 777)
8105         local perm_minus=(8 8 4 8 4 4 2
8106                           8 8 4 8 4 4 2
8107                           8 8 4 8 4 4 2
8108                           4 4 2 4 2 2 1)
8109         local perm_slash=(8  8 12  8 12 12 14
8110                           8  8 12  8 12 12 14
8111                           8  8 12  8 12 12 14
8112                          16 16 24 16 24 24 28)
8113
8114         test_mkdir "$dir"
8115         for perm in ${perms[*]}; do
8116                 touch "$dir/$tfile.$perm"
8117                 chmod $perm "$dir/$tfile.$perm"
8118         done
8119
8120         for ((i = 0; i < ${#perms[*]}; i++)); do
8121                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8122                 (( $num == 1 )) ||
8123                         error "lfs find -perm ${perms[i]}:"\
8124                               "$num != 1"
8125
8126                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8127                 (( $num == ${perm_minus[i]} )) ||
8128                         error "lfs find -perm -${perms[i]}:"\
8129                               "$num != ${perm_minus[i]}"
8130
8131                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8132                 (( $num == ${perm_slash[i]} )) ||
8133                         error "lfs find -perm /${perms[i]}:"\
8134                               "$num != ${perm_slash[i]}"
8135         done
8136 }
8137 run_test 56aca "check lfs find -perm with octal representation"
8138
8139 test_56acb() {
8140         local dir=$DIR/$tdir
8141         # p is the permission of write and execute for user, group and other
8142         # without the umask. It is used to test +wx.
8143         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8144         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8145         local symbolic=(+t  a+t u+t g+t o+t
8146                         g+s u+s o+s +s o+sr
8147                         o=r,ug+o,u+w
8148                         u+ g+ o+ a+ ugo+
8149                         u- g- o- a- ugo-
8150                         u= g= o= a= ugo=
8151                         o=r,ug+o,u+w u=r,a+u,u+w
8152                         g=r,ugo=g,u+w u+x,+X +X
8153                         u+x,u+X u+X u+x,g+X o+r,+X
8154                         u+x,go+X +wx +rwx)
8155
8156         test_mkdir $dir
8157         for perm in ${perms[*]}; do
8158                 touch "$dir/$tfile.$perm"
8159                 chmod $perm "$dir/$tfile.$perm"
8160         done
8161
8162         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8163                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8164
8165                 (( $num == 1 )) ||
8166                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8167         done
8168 }
8169 run_test 56acb "check lfs find -perm with symbolic representation"
8170
8171 test_56acc() {
8172         local dir=$DIR/$tdir
8173         local tests="17777 787 789 abcd
8174                 ug=uu ug=a ug=gu uo=ou urw
8175                 u+xg+x a=r,u+x,"
8176
8177         test_mkdir $dir
8178         for err in $tests; do
8179                 if $LFS find $dir -perm $err 2>/dev/null; then
8180                         error "lfs find -perm $err: parsing should have failed"
8181                 fi
8182         done
8183 }
8184 run_test 56acc "check parsing error for lfs find -perm"
8185
8186 test_56ba() {
8187         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8188                 skip "Need MDS version at least 2.10.50"
8189
8190         # Create composite files with one component
8191         local dir=$DIR/$tdir
8192
8193         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8194         # Create composite files with three components
8195         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8196         # Create non-composite files
8197         createmany -o $dir/${tfile}- 10
8198
8199         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8200
8201         [[ $nfiles == 10 ]] ||
8202                 error "lfs find -E 1M found $nfiles != 10 files"
8203
8204         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8205         [[ $nfiles == 25 ]] ||
8206                 error "lfs find ! -E 1M found $nfiles != 25 files"
8207
8208         # All files have a component that starts at 0
8209         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8210         [[ $nfiles == 35 ]] ||
8211                 error "lfs find --component-start 0 - $nfiles != 35 files"
8212
8213         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8214         [[ $nfiles == 15 ]] ||
8215                 error "lfs find --component-start 2M - $nfiles != 15 files"
8216
8217         # All files created here have a componenet that does not starts at 2M
8218         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8219         [[ $nfiles == 35 ]] ||
8220                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8221
8222         # Find files with a specified number of components
8223         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8224         [[ $nfiles == 15 ]] ||
8225                 error "lfs find --component-count 3 - $nfiles != 15 files"
8226
8227         # Remember non-composite files have a component count of zero
8228         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8229         [[ $nfiles == 10 ]] ||
8230                 error "lfs find --component-count 0 - $nfiles != 10 files"
8231
8232         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8233         [[ $nfiles == 20 ]] ||
8234                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8235
8236         # All files have a flag called "init"
8237         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8238         [[ $nfiles == 35 ]] ||
8239                 error "lfs find --component-flags init - $nfiles != 35 files"
8240
8241         # Multi-component files will have a component not initialized
8242         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8243         [[ $nfiles == 15 ]] ||
8244                 error "lfs find !--component-flags init - $nfiles != 15 files"
8245
8246         rm -rf $dir
8247
8248 }
8249 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8250
8251 test_56ca() {
8252         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8253                 skip "Need MDS version at least 2.10.57"
8254
8255         local td=$DIR/$tdir
8256         local tf=$td/$tfile
8257         local dir
8258         local nfiles
8259         local cmd
8260         local i
8261         local j
8262
8263         # create mirrored directories and mirrored files
8264         mkdir $td || error "mkdir $td failed"
8265         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8266         createmany -o $tf- 10 || error "create $tf- failed"
8267
8268         for i in $(seq 2); do
8269                 dir=$td/dir$i
8270                 mkdir $dir || error "mkdir $dir failed"
8271                 $LFS mirror create -N$((3 + i)) $dir ||
8272                         error "create mirrored dir $dir failed"
8273                 createmany -o $dir/$tfile- 10 ||
8274                         error "create $dir/$tfile- failed"
8275         done
8276
8277         # change the states of some mirrored files
8278         echo foo > $tf-6
8279         for i in $(seq 2); do
8280                 dir=$td/dir$i
8281                 for j in $(seq 4 9); do
8282                         echo foo > $dir/$tfile-$j
8283                 done
8284         done
8285
8286         # find mirrored files with specific mirror count
8287         cmd="$LFS find --mirror-count 3 --type f $td"
8288         nfiles=$($cmd | wc -l)
8289         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8290
8291         cmd="$LFS find ! --mirror-count 3 --type f $td"
8292         nfiles=$($cmd | wc -l)
8293         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8294
8295         cmd="$LFS find --mirror-count +2 --type f $td"
8296         nfiles=$($cmd | wc -l)
8297         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8298
8299         cmd="$LFS find --mirror-count -6 --type f $td"
8300         nfiles=$($cmd | wc -l)
8301         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8302
8303         # find mirrored files with specific file state
8304         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8305         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8306
8307         cmd="$LFS find --mirror-state=ro --type f $td"
8308         nfiles=$($cmd | wc -l)
8309         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8310
8311         cmd="$LFS find ! --mirror-state=ro --type f $td"
8312         nfiles=$($cmd | wc -l)
8313         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8314
8315         cmd="$LFS find --mirror-state=wp --type f $td"
8316         nfiles=$($cmd | wc -l)
8317         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8318
8319         cmd="$LFS find ! --mirror-state=sp --type f $td"
8320         nfiles=$($cmd | wc -l)
8321         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8322 }
8323 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8324
8325 test_56da() { # LU-14179
8326         local path=$DIR/$tdir
8327
8328         test_mkdir $path
8329         cd $path
8330
8331         local longdir=$(str_repeat 'a' 255)
8332
8333         for i in {1..15}; do
8334                 path=$path/$longdir
8335                 test_mkdir $longdir
8336                 cd $longdir
8337         done
8338
8339         local len=${#path}
8340         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8341
8342         test_mkdir $lastdir
8343         cd $lastdir
8344         # PATH_MAX-1
8345         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8346
8347         # NAME_MAX
8348         touch $(str_repeat 'f' 255)
8349
8350         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8351                 error "lfs find reported an error"
8352
8353         rm -rf $DIR/$tdir
8354 }
8355 run_test 56da "test lfs find with long paths"
8356
8357 test_56ea() { #LU-10378
8358         local path=$DIR/$tdir
8359         local pool=$TESTNAME
8360
8361         # Create ost pool
8362         pool_add $pool || error "pool_add $pool failed"
8363         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8364                 error "adding targets to $pool failed"
8365
8366         # Set default pool on directory before creating file
8367         mkdir $path || error "mkdir $path failed"
8368         $LFS setstripe -p $pool $path ||
8369                 error "set OST pool on $pool failed"
8370         touch $path/$tfile || error "touch $path/$tfile failed"
8371
8372         # Compare basic file attributes from -printf and stat
8373         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8374         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8375
8376         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8377                 error "Attrs from lfs find and stat don't match"
8378
8379         # Compare Lustre attributes from lfs find and lfs getstripe
8380         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8381         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8382         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8383         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8384         local fpool=$($LFS getstripe --pool $path/$tfile)
8385         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8386
8387         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8388                 error "Attrs from lfs find and lfs getstripe don't match"
8389
8390         # Verify behavior for unknown escape/format sequences
8391         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8392
8393         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8394                 error "Escape/format codes don't match"
8395 }
8396 run_test 56ea "test lfs find -printf option"
8397
8398 test_57a() {
8399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8400         # note test will not do anything if MDS is not local
8401         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8402                 skip_env "ldiskfs only test"
8403         fi
8404         remote_mds_nodsh && skip "remote MDS with nodsh"
8405
8406         local MNTDEV="osd*.*MDT*.mntdev"
8407         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8408         [ -z "$DEV" ] && error "can't access $MNTDEV"
8409         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8410                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8411                         error "can't access $DEV"
8412                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8413                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8414                 rm $TMP/t57a.dump
8415         done
8416 }
8417 run_test 57a "verify MDS filesystem created with large inodes =="
8418
8419 test_57b() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8422                 skip_env "ldiskfs only test"
8423         fi
8424         remote_mds_nodsh && skip "remote MDS with nodsh"
8425
8426         local dir=$DIR/$tdir
8427         local filecount=100
8428         local file1=$dir/f1
8429         local fileN=$dir/f$filecount
8430
8431         rm -rf $dir || error "removing $dir"
8432         test_mkdir -c1 $dir
8433         local mdtidx=$($LFS getstripe -m $dir)
8434         local mdtname=MDT$(printf %04x $mdtidx)
8435         local facet=mds$((mdtidx + 1))
8436
8437         echo "mcreating $filecount files"
8438         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8439
8440         # verify that files do not have EAs yet
8441         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8442                 error "$file1 has an EA"
8443         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8444                 error "$fileN has an EA"
8445
8446         sync
8447         sleep 1
8448         df $dir  #make sure we get new statfs data
8449         local mdsfree=$(do_facet $facet \
8450                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8451         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8452         local file
8453
8454         echo "opening files to create objects/EAs"
8455         for file in $(seq -f $dir/f%g 1 $filecount); do
8456                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8457                         error "opening $file"
8458         done
8459
8460         # verify that files have EAs now
8461         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8462         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8463
8464         sleep 1  #make sure we get new statfs data
8465         df $dir
8466         local mdsfree2=$(do_facet $facet \
8467                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8468         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8469
8470         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8471                 if [ "$mdsfree" != "$mdsfree2" ]; then
8472                         error "MDC before $mdcfree != after $mdcfree2"
8473                 else
8474                         echo "MDC before $mdcfree != after $mdcfree2"
8475                         echo "unable to confirm if MDS has large inodes"
8476                 fi
8477         fi
8478         rm -rf $dir
8479 }
8480 run_test 57b "default LOV EAs are stored inside large inodes ==="
8481
8482 test_58() {
8483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8484         [ -z "$(which wiretest 2>/dev/null)" ] &&
8485                         skip_env "could not find wiretest"
8486
8487         wiretest
8488 }
8489 run_test 58 "verify cross-platform wire constants =============="
8490
8491 test_59() {
8492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8493
8494         echo "touch 130 files"
8495         createmany -o $DIR/f59- 130
8496         echo "rm 130 files"
8497         unlinkmany $DIR/f59- 130
8498         sync
8499         # wait for commitment of removal
8500         wait_delete_completed
8501 }
8502 run_test 59 "verify cancellation of llog records async ========="
8503
8504 TEST60_HEAD="test_60 run $RANDOM"
8505 test_60a() {
8506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8507         remote_mgs_nodsh && skip "remote MGS with nodsh"
8508         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8509                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8510                         skip_env "missing subtest run-llog.sh"
8511
8512         log "$TEST60_HEAD - from kernel mode"
8513         do_facet mgs "$LCTL dk > /dev/null"
8514         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8515         do_facet mgs $LCTL dk > $TMP/$tfile
8516
8517         # LU-6388: test llog_reader
8518         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8519         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8520         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8521                         skip_env "missing llog_reader"
8522         local fstype=$(facet_fstype mgs)
8523         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8524                 skip_env "Only for ldiskfs or zfs type mgs"
8525
8526         local mntpt=$(facet_mntpt mgs)
8527         local mgsdev=$(mgsdevname 1)
8528         local fid_list
8529         local fid
8530         local rec_list
8531         local rec
8532         local rec_type
8533         local obj_file
8534         local path
8535         local seq
8536         local oid
8537         local pass=true
8538
8539         #get fid and record list
8540         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8541                 tail -n 4))
8542         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8543                 tail -n 4))
8544         #remount mgs as ldiskfs or zfs type
8545         stop mgs || error "stop mgs failed"
8546         mount_fstype mgs || error "remount mgs failed"
8547         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8548                 fid=${fid_list[i]}
8549                 rec=${rec_list[i]}
8550                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8551                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8552                 oid=$((16#$oid))
8553
8554                 case $fstype in
8555                         ldiskfs )
8556                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8557                         zfs )
8558                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8559                 esac
8560                 echo "obj_file is $obj_file"
8561                 do_facet mgs $llog_reader $obj_file
8562
8563                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8564                         awk '{ print $3 }' | sed -e "s/^type=//g")
8565                 if [ $rec_type != $rec ]; then
8566                         echo "FAILED test_60a wrong record type $rec_type," \
8567                               "should be $rec"
8568                         pass=false
8569                         break
8570                 fi
8571
8572                 #check obj path if record type is LLOG_LOGID_MAGIC
8573                 if [ "$rec" == "1064553b" ]; then
8574                         path=$(do_facet mgs $llog_reader $obj_file |
8575                                 grep "path=" | awk '{ print $NF }' |
8576                                 sed -e "s/^path=//g")
8577                         if [ $obj_file != $mntpt/$path ]; then
8578                                 echo "FAILED test_60a wrong obj path" \
8579                                       "$montpt/$path, should be $obj_file"
8580                                 pass=false
8581                                 break
8582                         fi
8583                 fi
8584         done
8585         rm -f $TMP/$tfile
8586         #restart mgs before "error", otherwise it will block the next test
8587         stop mgs || error "stop mgs failed"
8588         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8589         $pass || error "test failed, see FAILED test_60a messages for specifics"
8590 }
8591 run_test 60a "llog_test run from kernel module and test llog_reader"
8592
8593 test_60b() { # bug 6411
8594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8595
8596         dmesg > $DIR/$tfile
8597         LLOG_COUNT=$(do_facet mgs dmesg |
8598                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8599                           /llog_[a-z]*.c:[0-9]/ {
8600                                 if (marker)
8601                                         from_marker++
8602                                 from_begin++
8603                           }
8604                           END {
8605                                 if (marker)
8606                                         print from_marker
8607                                 else
8608                                         print from_begin
8609                           }")
8610
8611         [[ $LLOG_COUNT -gt 120 ]] &&
8612                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8613 }
8614 run_test 60b "limit repeated messages from CERROR/CWARN"
8615
8616 test_60c() {
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         echo "create 5000 files"
8620         createmany -o $DIR/f60c- 5000
8621 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8622         lctl set_param fail_loc=0x80000137
8623         unlinkmany $DIR/f60c- 5000
8624         lctl set_param fail_loc=0
8625 }
8626 run_test 60c "unlink file when mds full"
8627
8628 test_60d() {
8629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8630
8631         SAVEPRINTK=$(lctl get_param -n printk)
8632         # verify "lctl mark" is even working"
8633         MESSAGE="test message ID $RANDOM $$"
8634         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8635         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8636
8637         lctl set_param printk=0 || error "set lnet.printk failed"
8638         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8639         MESSAGE="new test message ID $RANDOM $$"
8640         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8641         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8642         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8643
8644         lctl set_param -n printk="$SAVEPRINTK"
8645 }
8646 run_test 60d "test printk console message masking"
8647
8648 test_60e() {
8649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8650         remote_mds_nodsh && skip "remote MDS with nodsh"
8651
8652         touch $DIR/$tfile
8653 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8654         do_facet mds1 lctl set_param fail_loc=0x15b
8655         rm $DIR/$tfile
8656 }
8657 run_test 60e "no space while new llog is being created"
8658
8659 test_60f() {
8660         local old_path=$($LCTL get_param -n debug_path)
8661
8662         stack_trap "$LCTL set_param debug_path=$old_path"
8663         stack_trap "rm -f $TMP/$tfile*"
8664         rm -f $TMP/$tfile* 2> /dev/null
8665         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8666         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8667         test_mkdir $DIR/$tdir
8668         # retry in case the open is cached and not released
8669         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8670                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8671                 sleep 0.1
8672         done
8673         ls $TMP/$tfile*
8674         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8675 }
8676 run_test 60f "change debug_path works"
8677
8678 test_60g() {
8679         local pid
8680         local i
8681
8682         test_mkdir -c $MDSCOUNT $DIR/$tdir
8683
8684         (
8685                 local index=0
8686                 while true; do
8687                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8688                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8689                                 2>/dev/null
8690                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8691                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8692                         index=$((index + 1))
8693                 done
8694         ) &
8695
8696         pid=$!
8697
8698         for i in {0..100}; do
8699                 # define OBD_FAIL_OSD_TXN_START    0x19a
8700                 local index=$((i % MDSCOUNT + 1))
8701
8702                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8703                         > /dev/null
8704                 sleep 0.01
8705         done
8706
8707         kill -9 $pid
8708
8709         for i in $(seq $MDSCOUNT); do
8710                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8711         done
8712
8713         mkdir $DIR/$tdir/new || error "mkdir failed"
8714         rmdir $DIR/$tdir/new || error "rmdir failed"
8715
8716         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8717                 -t namespace
8718         for i in $(seq $MDSCOUNT); do
8719                 wait_update_facet mds$i "$LCTL get_param -n \
8720                         mdd.$(facet_svc mds$i).lfsck_namespace |
8721                         awk '/^status/ { print \\\$2 }'" "completed"
8722         done
8723
8724         ls -R $DIR/$tdir
8725         rm -rf $DIR/$tdir || error "rmdir failed"
8726 }
8727 run_test 60g "transaction abort won't cause MDT hung"
8728
8729 test_60h() {
8730         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8731                 skip "Need MDS version at least 2.12.52"
8732         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8733
8734         local f
8735
8736         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8737         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8738         for fail_loc in 0x80000188 0x80000189; do
8739                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8740                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8741                         error "mkdir $dir-$fail_loc failed"
8742                 for i in {0..10}; do
8743                         # create may fail on missing stripe
8744                         echo $i > $DIR/$tdir-$fail_loc/$i
8745                 done
8746                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8747                         error "getdirstripe $tdir-$fail_loc failed"
8748                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8749                         error "migrate $tdir-$fail_loc failed"
8750                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8751                         error "getdirstripe $tdir-$fail_loc failed"
8752                 pushd $DIR/$tdir-$fail_loc
8753                 for f in *; do
8754                         echo $f | cmp $f - || error "$f data mismatch"
8755                 done
8756                 popd
8757                 rm -rf $DIR/$tdir-$fail_loc
8758         done
8759 }
8760 run_test 60h "striped directory with missing stripes can be accessed"
8761
8762 function t60i_load() {
8763         mkdir $DIR/$tdir
8764         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8765         $LCTL set_param fail_loc=0x131c fail_val=1
8766         for ((i=0; i<5000; i++)); do
8767                 touch $DIR/$tdir/f$i
8768         done
8769 }
8770
8771 test_60i() {
8772         changelog_register || error "changelog_register failed"
8773         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8774         changelog_users $SINGLEMDS | grep -q $cl_user ||
8775                 error "User $cl_user not found in changelog_users"
8776         changelog_chmask "ALL"
8777         t60i_load &
8778         local PID=$!
8779         for((i=0; i<100; i++)); do
8780                 changelog_dump >/dev/null ||
8781                         error "can't read changelog"
8782         done
8783         kill $PID
8784         wait $PID
8785         changelog_deregister || error "changelog_deregister failed"
8786         $LCTL set_param fail_loc=0
8787 }
8788 run_test 60i "llog: new record vs reader race"
8789
8790 test_61a() {
8791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8792
8793         f="$DIR/f61"
8794         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8795         cancel_lru_locks osc
8796         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8797         sync
8798 }
8799 run_test 61a "mmap() writes don't make sync hang ================"
8800
8801 test_61b() {
8802         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8803 }
8804 run_test 61b "mmap() of unstriped file is successful"
8805
8806 # bug 2330 - insufficient obd_match error checking causes LBUG
8807 test_62() {
8808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8809
8810         f="$DIR/f62"
8811         echo foo > $f
8812         cancel_lru_locks osc
8813         lctl set_param fail_loc=0x405
8814         cat $f && error "cat succeeded, expect -EIO"
8815         lctl set_param fail_loc=0
8816 }
8817 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8818 # match every page all of the time.
8819 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8820
8821 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8822 # Though this test is irrelevant anymore, it helped to reveal some
8823 # other grant bugs (LU-4482), let's keep it.
8824 test_63a() {   # was test_63
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826
8827         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8828
8829         for i in `seq 10` ; do
8830                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8831                 sleep 5
8832                 kill $!
8833                 sleep 1
8834         done
8835
8836         rm -f $DIR/f63 || true
8837 }
8838 run_test 63a "Verify oig_wait interruption does not crash ======="
8839
8840 # bug 2248 - async write errors didn't return to application on sync
8841 # bug 3677 - async write errors left page locked
8842 test_63b() {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844
8845         debugsave
8846         lctl set_param debug=-1
8847
8848         # ensure we have a grant to do async writes
8849         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8850         rm $DIR/$tfile
8851
8852         sync    # sync lest earlier test intercept the fail_loc
8853
8854         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8855         lctl set_param fail_loc=0x80000406
8856         $MULTIOP $DIR/$tfile Owy && \
8857                 error "sync didn't return ENOMEM"
8858         sync; sleep 2; sync     # do a real sync this time to flush page
8859         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8860                 error "locked page left in cache after async error" || true
8861         debugrestore
8862 }
8863 run_test 63b "async write errors should be returned to fsync ==="
8864
8865 test_64a () {
8866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8867
8868         lfs df $DIR
8869         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8870 }
8871 run_test 64a "verify filter grant calculations (in kernel) ====="
8872
8873 test_64b () {
8874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8875
8876         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8877 }
8878 run_test 64b "check out-of-space detection on client"
8879
8880 test_64c() {
8881         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8882 }
8883 run_test 64c "verify grant shrink"
8884
8885 import_param() {
8886         local tgt=$1
8887         local param=$2
8888
8889         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8890 }
8891
8892 # this does exactly what osc_request.c:osc_announce_cached() does in
8893 # order to calculate max amount of grants to ask from server
8894 want_grant() {
8895         local tgt=$1
8896
8897         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8898         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8899
8900         ((rpc_in_flight++));
8901         nrpages=$((nrpages * rpc_in_flight))
8902
8903         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8904
8905         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8906
8907         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8908         local undirty=$((nrpages * PAGE_SIZE))
8909
8910         local max_extent_pages
8911         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8912         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8913         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8914         local grant_extent_tax
8915         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8916
8917         undirty=$((undirty + nrextents * grant_extent_tax))
8918
8919         echo $undirty
8920 }
8921
8922 # this is size of unit for grant allocation. It should be equal to
8923 # what tgt_grant.c:tgt_grant_chunk() calculates
8924 grant_chunk() {
8925         local tgt=$1
8926         local max_brw_size
8927         local grant_extent_tax
8928
8929         max_brw_size=$(import_param $tgt max_brw_size)
8930
8931         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8932
8933         echo $(((max_brw_size + grant_extent_tax) * 2))
8934 }
8935
8936 test_64d() {
8937         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8938                 skip "OST < 2.10.55 doesn't limit grants enough"
8939
8940         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8941
8942         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8943                 skip "no grant_param connect flag"
8944
8945         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8946
8947         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8948         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8949
8950
8951         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8952         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8953
8954         $LFS setstripe $DIR/$tfile -i 0 -c 1
8955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8956         ddpid=$!
8957
8958         while kill -0 $ddpid; do
8959                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8960
8961                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8962                         kill $ddpid
8963                         error "cur_grant $cur_grant > $max_cur_granted"
8964                 fi
8965
8966                 sleep 1
8967         done
8968 }
8969 run_test 64d "check grant limit exceed"
8970
8971 check_grants() {
8972         local tgt=$1
8973         local expected=$2
8974         local msg=$3
8975         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8976
8977         ((cur_grants == expected)) ||
8978                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8979 }
8980
8981 round_up_p2() {
8982         echo $((($1 + $2 - 1) & ~($2 - 1)))
8983 }
8984
8985 test_64e() {
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8988                 skip "Need OSS version at least 2.11.56"
8989
8990         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8991         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8992         $LCTL set_param debug=+cache
8993
8994         # Remount client to reset grant
8995         remount_client $MOUNT || error "failed to remount client"
8996         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8997
8998         local init_grants=$(import_param $osc_tgt initial_grant)
8999
9000         check_grants $osc_tgt $init_grants "init grants"
9001
9002         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9003         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9004         local gbs=$(import_param $osc_tgt grant_block_size)
9005
9006         # write random number of bytes from max_brw_size / 4 to max_brw_size
9007         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9008         # align for direct io
9009         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9010         # round to grant consumption unit
9011         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9012
9013         local grants=$((wb_round_up + extent_tax))
9014
9015         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9016
9017         # define OBD_FAIL_TGT_NO_GRANT 0x725
9018         # make the server not grant more back
9019         do_facet ost1 $LCTL set_param fail_loc=0x725
9020         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9021
9022         do_facet ost1 $LCTL set_param fail_loc=0
9023
9024         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9025
9026         rm -f $DIR/$tfile || error "rm failed"
9027
9028         # Remount client to reset grant
9029         remount_client $MOUNT || error "failed to remount client"
9030         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9031
9032         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9033
9034         # define OBD_FAIL_TGT_NO_GRANT 0x725
9035         # make the server not grant more back
9036         do_facet ost1 $LCTL set_param fail_loc=0x725
9037         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9038         do_facet ost1 $LCTL set_param fail_loc=0
9039
9040         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9041 }
9042 run_test 64e "check grant consumption (no grant allocation)"
9043
9044 test_64f() {
9045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9046
9047         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9048         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9049         $LCTL set_param debug=+cache
9050
9051         # Remount client to reset grant
9052         remount_client $MOUNT || error "failed to remount client"
9053         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9054
9055         local init_grants=$(import_param $osc_tgt initial_grant)
9056         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9057         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9058         local gbs=$(import_param $osc_tgt grant_block_size)
9059         local chunk=$(grant_chunk $osc_tgt)
9060
9061         # write random number of bytes from max_brw_size / 4 to max_brw_size
9062         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9063         # align for direct io
9064         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9065         # round to grant consumption unit
9066         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9067
9068         local grants=$((wb_round_up + extent_tax))
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9071         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9072                 error "error writing to $DIR/$tfile"
9073
9074         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9075                 "direct io with grant allocation"
9076
9077         rm -f $DIR/$tfile || error "rm failed"
9078
9079         # Remount client to reset grant
9080         remount_client $MOUNT || error "failed to remount client"
9081         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9082
9083         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9084
9085         local cmd="oO_WRONLY:w${write_bytes}_yc"
9086
9087         $MULTIOP $DIR/$tfile $cmd &
9088         MULTIPID=$!
9089         sleep 1
9090
9091         check_grants $osc_tgt $((init_grants - grants)) \
9092                 "buffered io, not write rpc"
9093
9094         kill -USR1 $MULTIPID
9095         wait
9096
9097         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9098                 "buffered io, one RPC"
9099 }
9100 run_test 64f "check grant consumption (with grant allocation)"
9101
9102 test_64g() {
9103         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9104                 skip "Need MDS version at least 2.14.56"
9105
9106         local mdts=$(comma_list $(mdts_nodes))
9107
9108         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9109                         tr '\n' ' ')
9110         stack_trap "$LCTL set_param $old"
9111
9112         # generate dirty pages and increase dirty granted on MDT
9113         stack_trap "rm -f $DIR/$tfile-*"
9114         for (( i = 0; i < 10; i++)); do
9115                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9116                         error "can't set stripe"
9117                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9118                         error "can't dd"
9119                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9120                         $LFS getstripe $DIR/$tfile-$i
9121                         error "not DoM file"
9122                 }
9123         done
9124
9125         # flush dirty pages
9126         sync
9127
9128         # wait until grant shrink reset grant dirty on MDTs
9129         for ((i = 0; i < 120; i++)); do
9130                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9131                         awk '{sum=sum+$1} END {print sum}')
9132                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9133                 echo "$grant_dirty grants, $vm_dirty pages"
9134                 (( grant_dirty + vm_dirty == 0 )) && break
9135                 (( i == 3 )) && sync &&
9136                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9137                 sleep 1
9138         done
9139
9140         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9141                 awk '{sum=sum+$1} END {print sum}')
9142         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9143 }
9144 run_test 64g "grant shrink on MDT"
9145
9146 test_64h() {
9147         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9148                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9149
9150         local instance=$($LFS getname -i $DIR)
9151         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9152         local num_exps=$(do_facet ost1 \
9153             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9154         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9155         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9157
9158         # 10MiB is for file to be written, max_brw_size * 16 *
9159         # num_exps is space reserve so that tgt_grant_shrink() decided
9160         # to not shrink
9161         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9162         (( avail * 1024 < expect )) &&
9163                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9164
9165         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9166         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9167         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9168         $LCTL set_param osc.*OST0000*.grant_shrink=1
9169         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9170
9171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9173
9174         # drop cache so that coming read would do rpc
9175         cancel_lru_locks osc
9176
9177         # shrink interval is set to 10, pause for 7 seconds so that
9178         # grant thread did not wake up yet but coming read entered
9179         # shrink mode for rpc (osc_should_shrink_grant())
9180         sleep 7
9181
9182         declare -a cur_grant_bytes
9183         declare -a tot_granted
9184         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9185         tot_granted[0]=$(do_facet ost1 \
9186             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9187
9188         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9189
9190         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9191         tot_granted[1]=$(do_facet ost1 \
9192             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9193
9194         # grant change should be equal on both sides
9195         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9196                 tot_granted[0] - tot_granted[1])) ||
9197                 error "grant change mismatch, "                                \
9198                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9199                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9200 }
9201 run_test 64h "grant shrink on read"
9202
9203 test_64i() {
9204         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9205                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9206
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208         remote_ost_nodsh && skip "remote OSTs with nodsh"
9209
9210         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9211
9212         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9213
9214         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9215         local instance=$($LFS getname -i $DIR)
9216
9217         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9218         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9219
9220         # shrink grants and simulate rpc loss
9221         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9222         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9223         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9224
9225         fail ost1
9226
9227         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9228
9229         local testid=$(echo $TESTNAME | tr '_' ' ')
9230
9231         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9232                 grep "GRANT, real grant" &&
9233                 error "client has more grants then it owns" || true
9234 }
9235 run_test 64i "shrink on reconnect"
9236
9237 # bug 1414 - set/get directories' stripe info
9238 test_65a() {
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240
9241         test_mkdir $DIR/$tdir
9242         touch $DIR/$tdir/f1
9243         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9244 }
9245 run_test 65a "directory with no stripe info"
9246
9247 test_65b() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249
9250         test_mkdir $DIR/$tdir
9251         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9252
9253         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9254                                                 error "setstripe"
9255         touch $DIR/$tdir/f2
9256         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9257 }
9258 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9259
9260 test_65c() {
9261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9262         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9263
9264         test_mkdir $DIR/$tdir
9265         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9266
9267         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9268                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9269         touch $DIR/$tdir/f3
9270         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9271 }
9272 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9273
9274 test_65d() {
9275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9276
9277         test_mkdir $DIR/$tdir
9278         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9279         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9280
9281         if [[ $STRIPECOUNT -le 0 ]]; then
9282                 sc=1
9283         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9284                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9285                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9286         else
9287                 sc=$(($STRIPECOUNT - 1))
9288         fi
9289         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9290         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9291         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9292                 error "lverify failed"
9293 }
9294 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9295
9296 test_65e() {
9297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9298
9299         test_mkdir $DIR/$tdir
9300
9301         $LFS setstripe $DIR/$tdir || error "setstripe"
9302         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9303                                         error "no stripe info failed"
9304         touch $DIR/$tdir/f6
9305         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9306 }
9307 run_test 65e "directory setstripe defaults"
9308
9309 test_65f() {
9310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9311
9312         test_mkdir $DIR/${tdir}f
9313         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9314                 error "setstripe succeeded" || true
9315 }
9316 run_test 65f "dir setstripe permission (should return error) ==="
9317
9318 test_65g() {
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320
9321         test_mkdir $DIR/$tdir
9322         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9323
9324         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9325                 error "setstripe -S failed"
9326         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9327         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9328                 error "delete default stripe failed"
9329 }
9330 run_test 65g "directory setstripe -d"
9331
9332 test_65h() {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334
9335         test_mkdir $DIR/$tdir
9336         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9337
9338         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9339                 error "setstripe -S failed"
9340         test_mkdir $DIR/$tdir/dd1
9341         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9342                 error "stripe info inherit failed"
9343 }
9344 run_test 65h "directory stripe info inherit ===================="
9345
9346 test_65i() {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348
9349         save_layout_restore_at_exit $MOUNT
9350
9351         # bug6367: set non-default striping on root directory
9352         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9353
9354         # bug12836: getstripe on -1 default directory striping
9355         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9356
9357         # bug12836: getstripe -v on -1 default directory striping
9358         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9359
9360         # bug12836: new find on -1 default directory striping
9361         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9362 }
9363 run_test 65i "various tests to set root directory striping"
9364
9365 test_65j() { # bug6367
9366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9367
9368         sync; sleep 1
9369
9370         # if we aren't already remounting for each test, do so for this test
9371         if [ "$I_MOUNTED" = "yes" ]; then
9372                 cleanup || error "failed to unmount"
9373                 setup
9374         fi
9375
9376         save_layout_restore_at_exit $MOUNT
9377
9378         $LFS setstripe -d $MOUNT || error "setstripe failed"
9379 }
9380 run_test 65j "set default striping on root directory (bug 6367)="
9381
9382 cleanup_65k() {
9383         rm -rf $DIR/$tdir
9384         wait_delete_completed
9385         do_facet $SINGLEMDS "lctl set_param -n \
9386                 osp.$ost*MDT0000.max_create_count=$max_count"
9387         do_facet $SINGLEMDS "lctl set_param -n \
9388                 osp.$ost*MDT0000.create_count=$count"
9389         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9390         echo $INACTIVE_OSC "is Activate"
9391
9392         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9393 }
9394
9395 test_65k() { # bug11679
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9398         remote_mds_nodsh && skip "remote MDS with nodsh"
9399
9400         local disable_precreate=true
9401         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9402                 disable_precreate=false
9403
9404         echo "Check OST status: "
9405         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9406                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9407
9408         for OSC in $MDS_OSCS; do
9409                 echo $OSC "is active"
9410                 do_facet $SINGLEMDS lctl --device %$OSC activate
9411         done
9412
9413         for INACTIVE_OSC in $MDS_OSCS; do
9414                 local ost=$(osc_to_ost $INACTIVE_OSC)
9415                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9416                                lov.*md*.target_obd |
9417                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9418
9419                 mkdir -p $DIR/$tdir
9420                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9421                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9422
9423                 echo "Deactivate: " $INACTIVE_OSC
9424                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9425
9426                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9427                               osp.$ost*MDT0000.create_count")
9428                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9429                                   osp.$ost*MDT0000.max_create_count")
9430                 $disable_precreate &&
9431                         do_facet $SINGLEMDS "lctl set_param -n \
9432                                 osp.$ost*MDT0000.max_create_count=0"
9433
9434                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9435                         [ -f $DIR/$tdir/$idx ] && continue
9436                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9437                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9438                                 { cleanup_65k;
9439                                   error "setstripe $idx should succeed"; }
9440                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9441                 done
9442                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9443                 rmdir $DIR/$tdir
9444
9445                 do_facet $SINGLEMDS "lctl set_param -n \
9446                         osp.$ost*MDT0000.max_create_count=$max_count"
9447                 do_facet $SINGLEMDS "lctl set_param -n \
9448                         osp.$ost*MDT0000.create_count=$count"
9449                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9450                 echo $INACTIVE_OSC "is Activate"
9451
9452                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9453         done
9454 }
9455 run_test 65k "validate manual striping works properly with deactivated OSCs"
9456
9457 test_65l() { # bug 12836
9458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9459
9460         test_mkdir -p $DIR/$tdir/test_dir
9461         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9462         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9463 }
9464 run_test 65l "lfs find on -1 stripe dir ========================"
9465
9466 test_65m() {
9467         local layout=$(save_layout $MOUNT)
9468         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9469                 restore_layout $MOUNT $layout
9470                 error "setstripe should fail by non-root users"
9471         }
9472         true
9473 }
9474 run_test 65m "normal user can't set filesystem default stripe"
9475
9476 test_65n() {
9477         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9478         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9479                 skip "Need MDS version at least 2.12.50"
9480         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9481
9482         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9483         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9484         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9485
9486         save_layout_restore_at_exit $MOUNT
9487
9488         # new subdirectory under root directory should not inherit
9489         # the default layout from root
9490         local dir1=$MOUNT/$tdir-1
9491         mkdir $dir1 || error "mkdir $dir1 failed"
9492         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9493                 error "$dir1 shouldn't have LOV EA"
9494
9495         # delete the default layout on root directory
9496         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9497
9498         local dir2=$MOUNT/$tdir-2
9499         mkdir $dir2 || error "mkdir $dir2 failed"
9500         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9501                 error "$dir2 shouldn't have LOV EA"
9502
9503         # set a new striping pattern on root directory
9504         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9505         local new_def_stripe_size=$((def_stripe_size * 2))
9506         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9507                 error "set stripe size on $MOUNT failed"
9508
9509         # new file created in $dir2 should inherit the new stripe size from
9510         # the filesystem default
9511         local file2=$dir2/$tfile-2
9512         touch $file2 || error "touch $file2 failed"
9513
9514         local file2_stripe_size=$($LFS getstripe -S $file2)
9515         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9516         {
9517                 echo "file2_stripe_size: '$file2_stripe_size'"
9518                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9519                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9520         }
9521
9522         local dir3=$MOUNT/$tdir-3
9523         mkdir $dir3 || error "mkdir $dir3 failed"
9524         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9525         # the root layout, which is the actual default layout that will be used
9526         # when new files are created in $dir3.
9527         local dir3_layout=$(get_layout_param $dir3)
9528         local root_dir_layout=$(get_layout_param $MOUNT)
9529         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9530         {
9531                 echo "dir3_layout: '$dir3_layout'"
9532                 echo "root_dir_layout: '$root_dir_layout'"
9533                 error "$dir3 should show the default layout from $MOUNT"
9534         }
9535
9536         # set OST pool on root directory
9537         local pool=$TESTNAME
9538         pool_add $pool || error "add $pool failed"
9539         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9540                 error "add targets to $pool failed"
9541
9542         $LFS setstripe -p $pool $MOUNT ||
9543                 error "set OST pool on $MOUNT failed"
9544
9545         # new file created in $dir3 should inherit the pool from
9546         # the filesystem default
9547         local file3=$dir3/$tfile-3
9548         touch $file3 || error "touch $file3 failed"
9549
9550         local file3_pool=$($LFS getstripe -p $file3)
9551         [[ "$file3_pool" = "$pool" ]] ||
9552                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9553
9554         local dir4=$MOUNT/$tdir-4
9555         mkdir $dir4 || error "mkdir $dir4 failed"
9556         local dir4_layout=$(get_layout_param $dir4)
9557         root_dir_layout=$(get_layout_param $MOUNT)
9558         echo "$LFS getstripe -d $dir4"
9559         $LFS getstripe -d $dir4
9560         echo "$LFS getstripe -d $MOUNT"
9561         $LFS getstripe -d $MOUNT
9562         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9563         {
9564                 echo "dir4_layout: '$dir4_layout'"
9565                 echo "root_dir_layout: '$root_dir_layout'"
9566                 error "$dir4 should show the default layout from $MOUNT"
9567         }
9568
9569         # new file created in $dir4 should inherit the pool from
9570         # the filesystem default
9571         local file4=$dir4/$tfile-4
9572         touch $file4 || error "touch $file4 failed"
9573
9574         local file4_pool=$($LFS getstripe -p $file4)
9575         [[ "$file4_pool" = "$pool" ]] ||
9576                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9577
9578         # new subdirectory under non-root directory should inherit
9579         # the default layout from its parent directory
9580         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9581                 error "set directory layout on $dir4 failed"
9582
9583         local dir5=$dir4/$tdir-5
9584         mkdir $dir5 || error "mkdir $dir5 failed"
9585
9586         dir4_layout=$(get_layout_param $dir4)
9587         local dir5_layout=$(get_layout_param $dir5)
9588         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9589         {
9590                 echo "dir4_layout: '$dir4_layout'"
9591                 echo "dir5_layout: '$dir5_layout'"
9592                 error "$dir5 should inherit the default layout from $dir4"
9593         }
9594
9595         # though subdir under ROOT doesn't inherit default layout, but
9596         # its sub dir/file should be created with default layout.
9597         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9598         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9599                 skip "Need MDS version at least 2.12.59"
9600
9601         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9602         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9603         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9604
9605         if [ $default_lmv_hash == "none" ]; then
9606                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9607         else
9608                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9609                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9610         fi
9611
9612         $LFS setdirstripe -D -c 2 $MOUNT ||
9613                 error "setdirstripe -D -c 2 failed"
9614         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9615         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9616         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9617
9618         # $dir4 layout includes pool
9619         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9620         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9621                 error "pool lost on setstripe"
9622         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9623         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9624                 error "pool lost on compound layout setstripe"
9625 }
9626 run_test 65n "don't inherit default layout from root for new subdirectories"
9627
9628 # bug 2543 - update blocks count on client
9629 test_66() {
9630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9631
9632         local COUNT=${COUNT:-8}
9633         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9634         sync; sync_all_data; sync; sync_all_data
9635         cancel_lru_locks osc
9636         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9637         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9638 }
9639 run_test 66 "update inode blocks count on client ==============="
9640
9641 meminfo() {
9642         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9643 }
9644
9645 swap_used() {
9646         swapon -s | awk '($1 == "'$1'") { print $4 }'
9647 }
9648
9649 # bug5265, obdfilter oa2dentry return -ENOENT
9650 # #define OBD_FAIL_SRV_ENOENT 0x217
9651 test_69() {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653         remote_ost_nodsh && skip "remote OST with nodsh"
9654
9655         f="$DIR/$tfile"
9656         $LFS setstripe -c 1 -i 0 $f
9657
9658         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9659
9660         do_facet ost1 lctl set_param fail_loc=0x217
9661         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9662         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9663
9664         do_facet ost1 lctl set_param fail_loc=0
9665         $DIRECTIO write $f 0 2 || error "write error"
9666
9667         cancel_lru_locks osc
9668         $DIRECTIO read $f 0 1 || error "read error"
9669
9670         do_facet ost1 lctl set_param fail_loc=0x217
9671         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9672
9673         do_facet ost1 lctl set_param fail_loc=0
9674         rm -f $f
9675 }
9676 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9677
9678 test_71() {
9679         test_mkdir $DIR/$tdir
9680         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9681         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9682 }
9683 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9684
9685 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9687         [ "$RUNAS_ID" = "$UID" ] &&
9688                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9689         # Check that testing environment is properly set up. Skip if not
9690         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9691                 skip_env "User $RUNAS_ID does not exist - skipping"
9692
9693         touch $DIR/$tfile
9694         chmod 777 $DIR/$tfile
9695         chmod ug+s $DIR/$tfile
9696         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9697                 error "$RUNAS dd $DIR/$tfile failed"
9698         # See if we are still setuid/sgid
9699         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9700                 error "S/gid is not dropped on write"
9701         # Now test that MDS is updated too
9702         cancel_lru_locks mdc
9703         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9704                 error "S/gid is not dropped on MDS"
9705         rm -f $DIR/$tfile
9706 }
9707 run_test 72a "Test that remove suid works properly (bug5695) ===="
9708
9709 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9710         local perm
9711
9712         [ "$RUNAS_ID" = "$UID" ] &&
9713                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9714         [ "$RUNAS_ID" -eq 0 ] &&
9715                 skip_env "RUNAS_ID = 0 -- skipping"
9716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9717         # Check that testing environment is properly set up. Skip if not
9718         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9719                 skip_env "User $RUNAS_ID does not exist - skipping"
9720
9721         touch $DIR/${tfile}-f{g,u}
9722         test_mkdir $DIR/${tfile}-dg
9723         test_mkdir $DIR/${tfile}-du
9724         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9725         chmod g+s $DIR/${tfile}-{f,d}g
9726         chmod u+s $DIR/${tfile}-{f,d}u
9727         for perm in 777 2777 4777; do
9728                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9729                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9730                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9731                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9732         done
9733         true
9734 }
9735 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9736
9737 # bug 3462 - multiple simultaneous MDC requests
9738 test_73() {
9739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9740
9741         test_mkdir $DIR/d73-1
9742         test_mkdir $DIR/d73-2
9743         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9744         pid1=$!
9745
9746         lctl set_param fail_loc=0x80000129
9747         $MULTIOP $DIR/d73-1/f73-2 Oc &
9748         sleep 1
9749         lctl set_param fail_loc=0
9750
9751         $MULTIOP $DIR/d73-2/f73-3 Oc &
9752         pid3=$!
9753
9754         kill -USR1 $pid1
9755         wait $pid1 || return 1
9756
9757         sleep 25
9758
9759         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9760         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9761         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9762
9763         rm -rf $DIR/d73-*
9764 }
9765 run_test 73 "multiple MDC requests (should not deadlock)"
9766
9767 test_74a() { # bug 6149, 6184
9768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9769
9770         touch $DIR/f74a
9771         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9772         #
9773         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9774         # will spin in a tight reconnection loop
9775         $LCTL set_param fail_loc=0x8000030e
9776         # get any lock that won't be difficult - lookup works.
9777         ls $DIR/f74a
9778         $LCTL set_param fail_loc=0
9779         rm -f $DIR/f74a
9780         true
9781 }
9782 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9783
9784 test_74b() { # bug 13310
9785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9786
9787         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9788         #
9789         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9790         # will spin in a tight reconnection loop
9791         $LCTL set_param fail_loc=0x8000030e
9792         # get a "difficult" lock
9793         touch $DIR/f74b
9794         $LCTL set_param fail_loc=0
9795         rm -f $DIR/f74b
9796         true
9797 }
9798 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9799
9800 test_74c() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802
9803         #define OBD_FAIL_LDLM_NEW_LOCK
9804         $LCTL set_param fail_loc=0x319
9805         touch $DIR/$tfile && error "touch successful"
9806         $LCTL set_param fail_loc=0
9807         true
9808 }
9809 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9810
9811 slab_lic=/sys/kernel/slab/lustre_inode_cache
9812 num_objects() {
9813         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9814         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9815                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9816 }
9817
9818 test_76a() { # Now for b=20433, added originally in b=1443
9819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9820
9821         cancel_lru_locks osc
9822         # there may be some slab objects cached per core
9823         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9824         local before=$(num_objects)
9825         local count=$((512 * cpus))
9826         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9827         local margin=$((count / 10))
9828         if [[ -f $slab_lic/aliases ]]; then
9829                 local aliases=$(cat $slab_lic/aliases)
9830                 (( aliases > 0 )) && margin=$((margin * aliases))
9831         fi
9832
9833         echo "before slab objects: $before"
9834         for i in $(seq $count); do
9835                 touch $DIR/$tfile
9836                 rm -f $DIR/$tfile
9837         done
9838         cancel_lru_locks osc
9839         local after=$(num_objects)
9840         echo "created: $count, after slab objects: $after"
9841         # shared slab counts are not very accurate, allow significant margin
9842         # the main goal is that the cache growth is not permanently > $count
9843         while (( after > before + margin )); do
9844                 sleep 1
9845                 after=$(num_objects)
9846                 wait=$((wait + 1))
9847                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9848                 if (( wait > 60 )); then
9849                         error "inode slab grew from $before+$margin to $after"
9850                 fi
9851         done
9852 }
9853 run_test 76a "confirm clients recycle inodes properly ===="
9854
9855 test_76b() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9858
9859         local count=512
9860         local before=$(num_objects)
9861
9862         for i in $(seq $count); do
9863                 mkdir $DIR/$tdir
9864                 rmdir $DIR/$tdir
9865         done
9866
9867         local after=$(num_objects)
9868         local wait=0
9869
9870         while (( after > before )); do
9871                 sleep 1
9872                 after=$(num_objects)
9873                 wait=$((wait + 1))
9874                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9875                 if (( wait > 60 )); then
9876                         error "inode slab grew from $before to $after"
9877                 fi
9878         done
9879
9880         echo "slab objects before: $before, after: $after"
9881 }
9882 run_test 76b "confirm clients recycle directory inodes properly ===="
9883
9884 export ORIG_CSUM=""
9885 set_checksums()
9886 {
9887         # Note: in sptlrpc modes which enable its own bulk checksum, the
9888         # original crc32_le bulk checksum will be automatically disabled,
9889         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9890         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9891         # In this case set_checksums() will not be no-op, because sptlrpc
9892         # bulk checksum will be enabled all through the test.
9893
9894         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9895         lctl set_param -n osc.*.checksums $1
9896         return 0
9897 }
9898
9899 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9900                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9901 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9902                              tr -d [] | head -n1)}
9903 set_checksum_type()
9904 {
9905         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9906         rc=$?
9907         log "set checksum type to $1, rc = $rc"
9908         return $rc
9909 }
9910
9911 get_osc_checksum_type()
9912 {
9913         # arugment 1: OST name, like OST0000
9914         ost=$1
9915         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9916                         sed 's/.*\[\(.*\)\].*/\1/g')
9917         rc=$?
9918         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9919         echo $checksum_type
9920 }
9921
9922 F77_TMP=$TMP/f77-temp
9923 F77SZ=8
9924 setup_f77() {
9925         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9926                 error "error writing to $F77_TMP"
9927 }
9928
9929 test_77a() { # bug 10889
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931         $GSS && skip_env "could not run with gss"
9932
9933         [ ! -f $F77_TMP ] && setup_f77
9934         set_checksums 1
9935         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9936         set_checksums 0
9937         rm -f $DIR/$tfile
9938 }
9939 run_test 77a "normal checksum read/write operation"
9940
9941 test_77b() { # bug 10889
9942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9943         $GSS && skip_env "could not run with gss"
9944
9945         [ ! -f $F77_TMP ] && setup_f77
9946         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9947         $LCTL set_param fail_loc=0x80000409
9948         set_checksums 1
9949
9950         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9951                 error "dd error: $?"
9952         $LCTL set_param fail_loc=0
9953
9954         for algo in $CKSUM_TYPES; do
9955                 cancel_lru_locks osc
9956                 set_checksum_type $algo
9957                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9958                 $LCTL set_param fail_loc=0x80000408
9959                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9960                 $LCTL set_param fail_loc=0
9961         done
9962         set_checksums 0
9963         set_checksum_type $ORIG_CSUM_TYPE
9964         rm -f $DIR/$tfile
9965 }
9966 run_test 77b "checksum error on client write, read"
9967
9968 cleanup_77c() {
9969         trap 0
9970         set_checksums 0
9971         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9972         $check_ost &&
9973                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9974         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9975         $check_ost && [ -n "$ost_file_prefix" ] &&
9976                 do_facet ost1 rm -f ${ost_file_prefix}\*
9977 }
9978
9979 test_77c() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981         $GSS && skip_env "could not run with gss"
9982         remote_ost_nodsh && skip "remote OST with nodsh"
9983
9984         local bad1
9985         local osc_file_prefix
9986         local osc_file
9987         local check_ost=false
9988         local ost_file_prefix
9989         local ost_file
9990         local orig_cksum
9991         local dump_cksum
9992         local fid
9993
9994         # ensure corruption will occur on first OSS/OST
9995         $LFS setstripe -i 0 $DIR/$tfile
9996
9997         [ ! -f $F77_TMP ] && setup_f77
9998         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9999                 error "dd write error: $?"
10000         fid=$($LFS path2fid $DIR/$tfile)
10001
10002         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10003         then
10004                 check_ost=true
10005                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10006                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10007         else
10008                 echo "OSS do not support bulk pages dump upon error"
10009         fi
10010
10011         osc_file_prefix=$($LCTL get_param -n debug_path)
10012         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10013
10014         trap cleanup_77c EXIT
10015
10016         set_checksums 1
10017         # enable bulk pages dump upon error on Client
10018         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10019         # enable bulk pages dump upon error on OSS
10020         $check_ost &&
10021                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10022
10023         # flush Client cache to allow next read to reach OSS
10024         cancel_lru_locks osc
10025
10026         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10027         $LCTL set_param fail_loc=0x80000408
10028         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10029         $LCTL set_param fail_loc=0
10030
10031         rm -f $DIR/$tfile
10032
10033         # check cksum dump on Client
10034         osc_file=$(ls ${osc_file_prefix}*)
10035         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10036         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10037         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10038         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10039         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10040                      cksum)
10041         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10042         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10043                 error "dump content does not match on Client"
10044
10045         $check_ost || skip "No need to check cksum dump on OSS"
10046
10047         # check cksum dump on OSS
10048         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10049         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10050         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10051         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10052         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10053                 error "dump content does not match on OSS"
10054
10055         cleanup_77c
10056 }
10057 run_test 77c "checksum error on client read with debug"
10058
10059 test_77d() { # bug 10889
10060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10061         $GSS && skip_env "could not run with gss"
10062
10063         stack_trap "rm -f $DIR/$tfile"
10064         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10065         $LCTL set_param fail_loc=0x80000409
10066         set_checksums 1
10067         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10068                 error "direct write: rc=$?"
10069         $LCTL set_param fail_loc=0
10070         set_checksums 0
10071
10072         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10073         $LCTL set_param fail_loc=0x80000408
10074         set_checksums 1
10075         cancel_lru_locks osc
10076         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10077                 error "direct read: rc=$?"
10078         $LCTL set_param fail_loc=0
10079         set_checksums 0
10080 }
10081 run_test 77d "checksum error on OST direct write, read"
10082
10083 test_77f() { # bug 10889
10084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10085         $GSS && skip_env "could not run with gss"
10086
10087         set_checksums 1
10088         stack_trap "rm -f $DIR/$tfile"
10089         for algo in $CKSUM_TYPES; do
10090                 cancel_lru_locks osc
10091                 set_checksum_type $algo
10092                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10093                 $LCTL set_param fail_loc=0x409
10094                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10095                         error "direct write succeeded"
10096                 $LCTL set_param fail_loc=0
10097         done
10098         set_checksum_type $ORIG_CSUM_TYPE
10099         set_checksums 0
10100 }
10101 run_test 77f "repeat checksum error on write (expect error)"
10102
10103 test_77g() { # bug 10889
10104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10105         $GSS && skip_env "could not run with gss"
10106         remote_ost_nodsh && skip "remote OST with nodsh"
10107
10108         [ ! -f $F77_TMP ] && setup_f77
10109
10110         local file=$DIR/$tfile
10111         stack_trap "rm -f $file" EXIT
10112
10113         $LFS setstripe -c 1 -i 0 $file
10114         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10115         do_facet ost1 lctl set_param fail_loc=0x8000021a
10116         set_checksums 1
10117         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10118                 error "write error: rc=$?"
10119         do_facet ost1 lctl set_param fail_loc=0
10120         set_checksums 0
10121
10122         cancel_lru_locks osc
10123         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10124         do_facet ost1 lctl set_param fail_loc=0x8000021b
10125         set_checksums 1
10126         cmp $F77_TMP $file || error "file compare failed"
10127         do_facet ost1 lctl set_param fail_loc=0
10128         set_checksums 0
10129 }
10130 run_test 77g "checksum error on OST write, read"
10131
10132 test_77k() { # LU-10906
10133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10134         $GSS && skip_env "could not run with gss"
10135
10136         local cksum_param="osc.$FSNAME*.checksums"
10137         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10138         local checksum
10139         local i
10140
10141         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10142         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10143         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10144
10145         for i in 0 1; do
10146                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10147                         error "failed to set checksum=$i on MGS"
10148                 wait_update $HOSTNAME "$get_checksum" $i
10149                 #remount
10150                 echo "remount client, checksum should be $i"
10151                 remount_client $MOUNT || error "failed to remount client"
10152                 checksum=$(eval $get_checksum)
10153                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10154         done
10155         # remove persistent param to avoid races with checksum mountopt below
10156         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10157                 error "failed to delete checksum on MGS"
10158
10159         for opt in "checksum" "nochecksum"; do
10160                 #remount with mount option
10161                 echo "remount client with option $opt, checksum should be $i"
10162                 umount_client $MOUNT || error "failed to umount client"
10163                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10164                         error "failed to mount client with option '$opt'"
10165                 checksum=$(eval $get_checksum)
10166                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10167                 i=$((i - 1))
10168         done
10169
10170         remount_client $MOUNT || error "failed to remount client"
10171 }
10172 run_test 77k "enable/disable checksum correctly"
10173
10174 test_77l() {
10175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10176         $GSS && skip_env "could not run with gss"
10177
10178         set_checksums 1
10179         stack_trap "set_checksums $ORIG_CSUM" EXIT
10180         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10181
10182         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10183
10184         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10185         for algo in $CKSUM_TYPES; do
10186                 set_checksum_type $algo || error "fail to set checksum type $algo"
10187                 osc_algo=$(get_osc_checksum_type OST0000)
10188                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10189
10190                 # no locks, no reqs to let the connection idle
10191                 cancel_lru_locks osc
10192                 lru_resize_disable osc
10193                 wait_osc_import_state client ost1 IDLE
10194
10195                 # ensure ost1 is connected
10196                 stat $DIR/$tfile >/dev/null || error "can't stat"
10197                 wait_osc_import_state client ost1 FULL
10198
10199                 osc_algo=$(get_osc_checksum_type OST0000)
10200                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10201         done
10202         return 0
10203 }
10204 run_test 77l "preferred checksum type is remembered after reconnected"
10205
10206 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10207 rm -f $F77_TMP
10208 unset F77_TMP
10209
10210 test_77m() {
10211         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10212                 skip "Need at least version 2.14.52"
10213         local param=checksum_speed
10214
10215         $LCTL get_param $param || error "reading $param failed"
10216
10217         csum_speeds=$($LCTL get_param -n $param)
10218
10219         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10220                 error "known checksum types are missing"
10221 }
10222 run_test 77m "Verify checksum_speed is correctly read"
10223
10224 check_filefrag_77n() {
10225         local nr_ext=0
10226         local starts=()
10227         local ends=()
10228
10229         while read extidx a b start end rest; do
10230                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10231                         nr_ext=$(( $nr_ext + 1 ))
10232                         starts+=( ${start%..} )
10233                         ends+=( ${end%:} )
10234                 fi
10235         done < <( filefrag -sv $1 )
10236
10237         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10238         return 1
10239 }
10240
10241 test_77n() {
10242         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10243
10244         touch $DIR/$tfile
10245         $TRUNCATE $DIR/$tfile 0
10246         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10247         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10248         check_filefrag_77n $DIR/$tfile ||
10249                 skip "$tfile blocks not contiguous around hole"
10250
10251         set_checksums 1
10252         stack_trap "set_checksums $ORIG_CSUM" EXIT
10253         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10254         stack_trap "rm -f $DIR/$tfile"
10255
10256         for algo in $CKSUM_TYPES; do
10257                 if [[ "$algo" =~ ^t10 ]]; then
10258                         set_checksum_type $algo ||
10259                                 error "fail to set checksum type $algo"
10260                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10261                                 error "fail to read $tfile with $algo"
10262                 fi
10263         done
10264         rm -f $DIR/$tfile
10265         return 0
10266 }
10267 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10268
10269 test_77o() {
10270         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10271                 skip "Need MDS version at least 2.14.55"
10272         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10273                 skip "Need OST version at least 2.14.55"
10274         local ofd=obdfilter
10275         local mdt=mdt
10276
10277         # print OST checksum_type
10278         echo "$ofd.$FSNAME-*.checksum_type:"
10279         do_nodes $(comma_list $(osts_nodes)) \
10280                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10281
10282         # print MDT checksum_type
10283         echo "$mdt.$FSNAME-*.checksum_type:"
10284         do_nodes $(comma_list $(mdts_nodes)) \
10285                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10286
10287         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10288                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10289
10290         (( $o_count == $OSTCOUNT )) ||
10291                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10292
10293         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10294                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10295
10296         (( $m_count == $MDSCOUNT )) ||
10297                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10298 }
10299 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10300
10301 cleanup_test_78() {
10302         trap 0
10303         rm -f $DIR/$tfile
10304 }
10305
10306 test_78() { # bug 10901
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308         remote_ost || skip_env "local OST"
10309
10310         NSEQ=5
10311         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10312         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10313         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10314         echo "MemTotal: $MEMTOTAL"
10315
10316         # reserve 256MB of memory for the kernel and other running processes,
10317         # and then take 1/2 of the remaining memory for the read/write buffers.
10318         if [ $MEMTOTAL -gt 512 ] ;then
10319                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10320         else
10321                 # for those poor memory-starved high-end clusters...
10322                 MEMTOTAL=$((MEMTOTAL / 2))
10323         fi
10324         echo "Mem to use for directio: $MEMTOTAL"
10325
10326         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10327         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10328         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10329         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10330                 head -n1)
10331         echo "Smallest OST: $SMALLESTOST"
10332         [[ $SMALLESTOST -lt 10240 ]] &&
10333                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10334
10335         trap cleanup_test_78 EXIT
10336
10337         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10338                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10339
10340         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10341         echo "File size: $F78SIZE"
10342         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10343         for i in $(seq 1 $NSEQ); do
10344                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10345                 echo directIO rdwr round $i of $NSEQ
10346                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10347         done
10348
10349         cleanup_test_78
10350 }
10351 run_test 78 "handle large O_DIRECT writes correctly ============"
10352
10353 test_79() { # bug 12743
10354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10355
10356         wait_delete_completed
10357
10358         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10359         BKFREE=$(calc_osc_kbytes kbytesfree)
10360         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10361
10362         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10363         DFTOTAL=`echo $STRING | cut -d, -f1`
10364         DFUSED=`echo $STRING  | cut -d, -f2`
10365         DFAVAIL=`echo $STRING | cut -d, -f3`
10366         DFFREE=$(($DFTOTAL - $DFUSED))
10367
10368         ALLOWANCE=$((64 * $OSTCOUNT))
10369
10370         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10371            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10372                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10373         fi
10374         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10375            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10376                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10377         fi
10378         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10379            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10380                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10381         fi
10382 }
10383 run_test 79 "df report consistency check ======================="
10384
10385 test_80() { # bug 10718
10386         remote_ost_nodsh && skip "remote OST with nodsh"
10387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10388
10389         # relax strong synchronous semantics for slow backends like ZFS
10390         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10391                 local soc="obdfilter.*.sync_lock_cancel"
10392                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10393
10394                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10395                 if [ -z "$save" ]; then
10396                         soc="obdfilter.*.sync_on_lock_cancel"
10397                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10398                 fi
10399
10400                 if [ "$save" != "never" ]; then
10401                         local hosts=$(comma_list $(osts_nodes))
10402
10403                         do_nodes $hosts $LCTL set_param $soc=never
10404                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10405                 fi
10406         fi
10407
10408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10409         sync; sleep 1; sync
10410         local before=$(date +%s)
10411         cancel_lru_locks osc
10412         local after=$(date +%s)
10413         local diff=$((after - before))
10414         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10415
10416         rm -f $DIR/$tfile
10417 }
10418 run_test 80 "Page eviction is equally fast at high offsets too"
10419
10420 test_81a() { # LU-456
10421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10422         remote_ost_nodsh && skip "remote OST with nodsh"
10423
10424         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10425         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10426         do_facet ost1 lctl set_param fail_loc=0x80000228
10427
10428         # write should trigger a retry and success
10429         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10430         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10431         RC=$?
10432         if [ $RC -ne 0 ] ; then
10433                 error "write should success, but failed for $RC"
10434         fi
10435 }
10436 run_test 81a "OST should retry write when get -ENOSPC ==============="
10437
10438 test_81b() { # LU-456
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440         remote_ost_nodsh && skip "remote OST with nodsh"
10441
10442         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10443         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10444         do_facet ost1 lctl set_param fail_loc=0x228
10445
10446         # write should retry several times and return -ENOSPC finally
10447         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10449         RC=$?
10450         ENOSPC=28
10451         if [ $RC -ne $ENOSPC ] ; then
10452                 error "dd should fail for -ENOSPC, but succeed."
10453         fi
10454 }
10455 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10456
10457 test_99() {
10458         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10459
10460         test_mkdir $DIR/$tdir.cvsroot
10461         chown $RUNAS_ID $DIR/$tdir.cvsroot
10462
10463         cd $TMP
10464         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10465
10466         cd /etc/init.d
10467         # some versions of cvs import exit(1) when asked to import links or
10468         # files they can't read.  ignore those files.
10469         local toignore=$(find . -type l -printf '-I %f\n' -o \
10470                          ! -perm /4 -printf '-I %f\n')
10471         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10472                 $tdir.reposname vtag rtag
10473
10474         cd $DIR
10475         test_mkdir $DIR/$tdir.reposname
10476         chown $RUNAS_ID $DIR/$tdir.reposname
10477         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10478
10479         cd $DIR/$tdir.reposname
10480         $RUNAS touch foo99
10481         $RUNAS cvs add -m 'addmsg' foo99
10482         $RUNAS cvs update
10483         $RUNAS cvs commit -m 'nomsg' foo99
10484         rm -fr $DIR/$tdir.cvsroot
10485 }
10486 run_test 99 "cvs strange file/directory operations"
10487
10488 test_100() {
10489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10490         [[ "$NETTYPE" =~ tcp ]] ||
10491                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10492         remote_ost_nodsh && skip "remote OST with nodsh"
10493         remote_mds_nodsh && skip "remote MDS with nodsh"
10494         remote_servers ||
10495                 skip "useless for local single node setup"
10496
10497         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10498                 [ "$PROT" != "tcp" ] && continue
10499                 RPORT=$(echo $REMOTE | cut -d: -f2)
10500                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10501
10502                 rc=0
10503                 LPORT=`echo $LOCAL | cut -d: -f2`
10504                 if [ $LPORT -ge 1024 ]; then
10505                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10506                         netstat -tna
10507                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10508                 fi
10509         done
10510         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10511 }
10512 run_test 100 "check local port using privileged port ==========="
10513
10514 function get_named_value()
10515 {
10516     local tag=$1
10517
10518     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10519 }
10520
10521 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10522                    awk '/^max_cached_mb/ { print $2 }')
10523
10524 cleanup_101a() {
10525         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10526         trap 0
10527 }
10528
10529 test_101a() {
10530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10531
10532         local s
10533         local discard
10534         local nreads=10000
10535         local cache_limit=32
10536
10537         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10538         trap cleanup_101a EXIT
10539         $LCTL set_param -n llite.*.read_ahead_stats=0
10540         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10541
10542         #
10543         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10544         #
10545         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10546         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10547
10548         discard=0
10549         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10550                    get_named_value 'read.but.discarded'); do
10551                         discard=$(($discard + $s))
10552         done
10553         cleanup_101a
10554
10555         $LCTL get_param osc.*-osc*.rpc_stats
10556         $LCTL get_param llite.*.read_ahead_stats
10557
10558         # Discard is generally zero, but sometimes a few random reads line up
10559         # and trigger larger readahead, which is wasted & leads to discards.
10560         if [[ $(($discard)) -gt $nreads ]]; then
10561                 error "too many ($discard) discarded pages"
10562         fi
10563         rm -f $DIR/$tfile || true
10564 }
10565 run_test 101a "check read-ahead for random reads"
10566
10567 setup_test101bc() {
10568         test_mkdir $DIR/$tdir
10569         local ssize=$1
10570         local FILE_LENGTH=$2
10571         STRIPE_OFFSET=0
10572
10573         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10574
10575         local list=$(comma_list $(osts_nodes))
10576         set_osd_param $list '' read_cache_enable 0
10577         set_osd_param $list '' writethrough_cache_enable 0
10578
10579         trap cleanup_test101bc EXIT
10580         # prepare the read-ahead file
10581         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10582
10583         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10584                                 count=$FILE_SIZE_MB 2> /dev/null
10585
10586 }
10587
10588 cleanup_test101bc() {
10589         trap 0
10590         rm -rf $DIR/$tdir
10591         rm -f $DIR/$tfile
10592
10593         local list=$(comma_list $(osts_nodes))
10594         set_osd_param $list '' read_cache_enable 1
10595         set_osd_param $list '' writethrough_cache_enable 1
10596 }
10597
10598 calc_total() {
10599         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10600 }
10601
10602 ra_check_101() {
10603         local read_size=$1
10604         local stripe_size=$2
10605         local stride_length=$((stripe_size / read_size))
10606         local stride_width=$((stride_length * OSTCOUNT))
10607         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10608                                 (stride_width - stride_length) ))
10609         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10610                   get_named_value 'read.but.discarded' | calc_total)
10611
10612         if [[ $discard -gt $discard_limit ]]; then
10613                 $LCTL get_param llite.*.read_ahead_stats
10614                 error "($discard) discarded pages with size (${read_size})"
10615         else
10616                 echo "Read-ahead success for size ${read_size}"
10617         fi
10618 }
10619
10620 test_101b() {
10621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10623
10624         local STRIPE_SIZE=1048576
10625         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10626
10627         if [ $SLOW == "yes" ]; then
10628                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10629         else
10630                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10631         fi
10632
10633         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10634
10635         # prepare the read-ahead file
10636         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10637         cancel_lru_locks osc
10638         for BIDX in 2 4 8 16 32 64 128 256
10639         do
10640                 local BSIZE=$((BIDX*4096))
10641                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10642                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10643                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10644                 $LCTL set_param -n llite.*.read_ahead_stats=0
10645                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10646                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10647                 cancel_lru_locks osc
10648                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10649         done
10650         cleanup_test101bc
10651         true
10652 }
10653 run_test 101b "check stride-io mode read-ahead ================="
10654
10655 test_101c() {
10656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10657
10658         local STRIPE_SIZE=1048576
10659         local FILE_LENGTH=$((STRIPE_SIZE*100))
10660         local nreads=10000
10661         local rsize=65536
10662         local osc_rpc_stats
10663
10664         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10665
10666         cancel_lru_locks osc
10667         $LCTL set_param osc.*.rpc_stats=0
10668         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10669         $LCTL get_param osc.*.rpc_stats
10670         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10671                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10672                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10673                 local size
10674
10675                 if [ $lines -le 20 ]; then
10676                         echo "continue debug"
10677                         continue
10678                 fi
10679                 for size in 1 2 4 8; do
10680                         local rpc=$(echo "$stats" |
10681                                     awk '($1 == "'$size':") {print $2; exit; }')
10682                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10683                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10684                 done
10685                 echo "$osc_rpc_stats check passed!"
10686         done
10687         cleanup_test101bc
10688         true
10689 }
10690 run_test 101c "check stripe_size aligned read-ahead"
10691
10692 test_101d() {
10693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10694
10695         local file=$DIR/$tfile
10696         local sz_MB=${FILESIZE_101d:-80}
10697         local ra_MB=${READAHEAD_MB:-40}
10698
10699         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10700         [ $free_MB -lt $sz_MB ] &&
10701                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10702
10703         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10704         $LFS setstripe -c -1 $file || error "setstripe failed"
10705
10706         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10707         echo Cancel LRU locks on lustre client to flush the client cache
10708         cancel_lru_locks osc
10709
10710         echo Disable read-ahead
10711         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10712         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10713         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10714         $LCTL get_param -n llite.*.max_read_ahead_mb
10715
10716         echo "Reading the test file $file with read-ahead disabled"
10717         local sz_KB=$((sz_MB * 1024 / 4))
10718         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10719         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10720         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10721                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10722
10723         echo "Cancel LRU locks on lustre client to flush the client cache"
10724         cancel_lru_locks osc
10725         echo Enable read-ahead with ${ra_MB}MB
10726         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10727
10728         echo "Reading the test file $file with read-ahead enabled"
10729         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10730                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10731
10732         echo "read-ahead disabled time read $raOFF"
10733         echo "read-ahead enabled time read $raON"
10734
10735         rm -f $file
10736         wait_delete_completed
10737
10738         # use awk for this check instead of bash because it handles decimals
10739         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10740                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10741 }
10742 run_test 101d "file read with and without read-ahead enabled"
10743
10744 test_101e() {
10745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10746
10747         local file=$DIR/$tfile
10748         local size_KB=500  #KB
10749         local count=100
10750         local bsize=1024
10751
10752         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10753         local need_KB=$((count * size_KB))
10754         [[ $free_KB -le $need_KB ]] &&
10755                 skip_env "Need free space $need_KB, have $free_KB"
10756
10757         echo "Creating $count ${size_KB}K test files"
10758         for ((i = 0; i < $count; i++)); do
10759                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10760         done
10761
10762         echo "Cancel LRU locks on lustre client to flush the client cache"
10763         cancel_lru_locks $OSC
10764
10765         echo "Reset readahead stats"
10766         $LCTL set_param -n llite.*.read_ahead_stats=0
10767
10768         for ((i = 0; i < $count; i++)); do
10769                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10770         done
10771
10772         $LCTL get_param llite.*.max_cached_mb
10773         $LCTL get_param llite.*.read_ahead_stats
10774         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10775                      get_named_value 'misses' | calc_total)
10776
10777         for ((i = 0; i < $count; i++)); do
10778                 rm -rf $file.$i 2>/dev/null
10779         done
10780
10781         #10000 means 20% reads are missing in readahead
10782         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10783 }
10784 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10785
10786 test_101f() {
10787         which iozone || skip_env "no iozone installed"
10788
10789         local old_debug=$($LCTL get_param debug)
10790         old_debug=${old_debug#*=}
10791         $LCTL set_param debug="reada mmap"
10792
10793         # create a test file
10794         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10795
10796         echo Cancel LRU locks on lustre client to flush the client cache
10797         cancel_lru_locks osc
10798
10799         echo Reset readahead stats
10800         $LCTL set_param -n llite.*.read_ahead_stats=0
10801
10802         echo mmap read the file with small block size
10803         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10804                 > /dev/null 2>&1
10805
10806         echo checking missing pages
10807         $LCTL get_param llite.*.read_ahead_stats
10808         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10809                         get_named_value 'misses' | calc_total)
10810
10811         $LCTL set_param debug="$old_debug"
10812         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10813         rm -f $DIR/$tfile
10814 }
10815 run_test 101f "check mmap read performance"
10816
10817 test_101g_brw_size_test() {
10818         local mb=$1
10819         local pages=$((mb * 1048576 / PAGE_SIZE))
10820         local file=$DIR/$tfile
10821
10822         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10823                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10824         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10825                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10826                         return 2
10827         done
10828
10829         stack_trap "rm -f $file" EXIT
10830         $LCTL set_param -n osc.*.rpc_stats=0
10831
10832         # 10 RPCs should be enough for the test
10833         local count=10
10834         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10835                 { error "dd write ${mb} MB blocks failed"; return 3; }
10836         cancel_lru_locks osc
10837         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10838                 { error "dd write ${mb} MB blocks failed"; return 4; }
10839
10840         # calculate number of full-sized read and write RPCs
10841         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10842                 sed -n '/pages per rpc/,/^$/p' |
10843                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10844                 END { print reads,writes }'))
10845         # allow one extra full-sized read RPC for async readahead
10846         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10847                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10848         [[ ${rpcs[1]} == $count ]] ||
10849                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10850 }
10851
10852 test_101g() {
10853         remote_ost_nodsh && skip "remote OST with nodsh"
10854
10855         local rpcs
10856         local osts=$(get_facets OST)
10857         local list=$(comma_list $(osts_nodes))
10858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10859         local brw_size="obdfilter.*.brw_size"
10860
10861         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10862
10863         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10864
10865         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10866                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10867                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10868            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10869                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10870                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10871
10872                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10873                         suffix="M"
10874
10875                 if [[ $orig_mb -lt 16 ]]; then
10876                         save_lustre_params $osts "$brw_size" > $p
10877                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10878                                 error "set 16MB RPC size failed"
10879
10880                         echo "remount client to enable new RPC size"
10881                         remount_client $MOUNT || error "remount_client failed"
10882                 fi
10883
10884                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10885                 # should be able to set brw_size=12, but no rpc_stats for that
10886                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10887         fi
10888
10889         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10890
10891         if [[ $orig_mb -lt 16 ]]; then
10892                 restore_lustre_params < $p
10893                 remount_client $MOUNT || error "remount_client restore failed"
10894         fi
10895
10896         rm -f $p $DIR/$tfile
10897 }
10898 run_test 101g "Big bulk(4/16 MiB) readahead"
10899
10900 test_101h() {
10901         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10902
10903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10904                 error "dd 70M file failed"
10905         echo Cancel LRU locks on lustre client to flush the client cache
10906         cancel_lru_locks osc
10907
10908         echo "Reset readahead stats"
10909         $LCTL set_param -n llite.*.read_ahead_stats 0
10910
10911         echo "Read 10M of data but cross 64M bundary"
10912         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10913         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10914                      get_named_value 'misses' | calc_total)
10915         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10916         rm -f $p $DIR/$tfile
10917 }
10918 run_test 101h "Readahead should cover current read window"
10919
10920 test_101i() {
10921         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10922                 error "dd 10M file failed"
10923
10924         local max_per_file_mb=$($LCTL get_param -n \
10925                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10926         cancel_lru_locks osc
10927         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10928         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10929                 error "set max_read_ahead_per_file_mb to 1 failed"
10930
10931         echo "Reset readahead stats"
10932         $LCTL set_param llite.*.read_ahead_stats=0
10933
10934         dd if=$DIR/$tfile of=/dev/null bs=2M
10935
10936         $LCTL get_param llite.*.read_ahead_stats
10937         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10938                      awk '/misses/ { print $2 }')
10939         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10940         rm -f $DIR/$tfile
10941 }
10942 run_test 101i "allow current readahead to exceed reservation"
10943
10944 test_101j() {
10945         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10946                 error "setstripe $DIR/$tfile failed"
10947         local file_size=$((1048576 * 16))
10948         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10949         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10950
10951         echo Disable read-ahead
10952         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10953
10954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10955         for blk in $PAGE_SIZE 1048576 $file_size; do
10956                 cancel_lru_locks osc
10957                 echo "Reset readahead stats"
10958                 $LCTL set_param -n llite.*.read_ahead_stats=0
10959                 local count=$(($file_size / $blk))
10960                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10961                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10962                              get_named_value 'failed.to.fast.read' | calc_total)
10963                 $LCTL get_param -n llite.*.read_ahead_stats
10964                 [ $miss -eq $count ] || error "expected $count got $miss"
10965         done
10966
10967         rm -f $p $DIR/$tfile
10968 }
10969 run_test 101j "A complete read block should be submitted when no RA"
10970
10971 setup_test102() {
10972         test_mkdir $DIR/$tdir
10973         chown $RUNAS_ID $DIR/$tdir
10974         STRIPE_SIZE=65536
10975         STRIPE_OFFSET=1
10976         STRIPE_COUNT=$OSTCOUNT
10977         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10978
10979         trap cleanup_test102 EXIT
10980         cd $DIR
10981         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10982         cd $DIR/$tdir
10983         for num in 1 2 3 4; do
10984                 for count in $(seq 1 $STRIPE_COUNT); do
10985                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10986                                 local size=`expr $STRIPE_SIZE \* $num`
10987                                 local file=file"$num-$idx-$count"
10988                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10989                         done
10990                 done
10991         done
10992
10993         cd $DIR
10994         $1 tar cf $TMP/f102.tar $tdir --xattrs
10995 }
10996
10997 cleanup_test102() {
10998         trap 0
10999         rm -f $TMP/f102.tar
11000         rm -rf $DIR/d0.sanity/d102
11001 }
11002
11003 test_102a() {
11004         [ "$UID" != 0 ] && skip "must run as root"
11005         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11006                 skip_env "must have user_xattr"
11007
11008         [ -z "$(which setfattr 2>/dev/null)" ] &&
11009                 skip_env "could not find setfattr"
11010
11011         local testfile=$DIR/$tfile
11012
11013         touch $testfile
11014         echo "set/get xattr..."
11015         setfattr -n trusted.name1 -v value1 $testfile ||
11016                 error "setfattr -n trusted.name1=value1 $testfile failed"
11017         getfattr -n trusted.name1 $testfile 2> /dev/null |
11018           grep "trusted.name1=.value1" ||
11019                 error "$testfile missing trusted.name1=value1"
11020
11021         setfattr -n user.author1 -v author1 $testfile ||
11022                 error "setfattr -n user.author1=author1 $testfile failed"
11023         getfattr -n user.author1 $testfile 2> /dev/null |
11024           grep "user.author1=.author1" ||
11025                 error "$testfile missing trusted.author1=author1"
11026
11027         echo "listxattr..."
11028         setfattr -n trusted.name2 -v value2 $testfile ||
11029                 error "$testfile unable to set trusted.name2"
11030         setfattr -n trusted.name3 -v value3 $testfile ||
11031                 error "$testfile unable to set trusted.name3"
11032         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11033             grep "trusted.name" | wc -l) -eq 3 ] ||
11034                 error "$testfile missing 3 trusted.name xattrs"
11035
11036         setfattr -n user.author2 -v author2 $testfile ||
11037                 error "$testfile unable to set user.author2"
11038         setfattr -n user.author3 -v author3 $testfile ||
11039                 error "$testfile unable to set user.author3"
11040         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11041             grep "user.author" | wc -l) -eq 3 ] ||
11042                 error "$testfile missing 3 user.author xattrs"
11043
11044         echo "remove xattr..."
11045         setfattr -x trusted.name1 $testfile ||
11046                 error "$testfile error deleting trusted.name1"
11047         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11048                 error "$testfile did not delete trusted.name1 xattr"
11049
11050         setfattr -x user.author1 $testfile ||
11051                 error "$testfile error deleting user.author1"
11052         echo "set lustre special xattr ..."
11053         $LFS setstripe -c1 $testfile
11054         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11055                 awk -F "=" '/trusted.lov/ { print $2 }' )
11056         setfattr -n "trusted.lov" -v $lovea $testfile ||
11057                 error "$testfile doesn't ignore setting trusted.lov again"
11058         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11059                 error "$testfile allow setting invalid trusted.lov"
11060         rm -f $testfile
11061 }
11062 run_test 102a "user xattr test =================================="
11063
11064 check_102b_layout() {
11065         local layout="$*"
11066         local testfile=$DIR/$tfile
11067
11068         echo "test layout '$layout'"
11069         $LFS setstripe $layout $testfile || error "setstripe failed"
11070         $LFS getstripe -y $testfile
11071
11072         echo "get/set/list trusted.lov xattr ..." # b=10930
11073         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11074         [[ "$value" =~ "trusted.lov" ]] ||
11075                 error "can't get trusted.lov from $testfile"
11076         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11077                 error "getstripe failed"
11078
11079         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11080
11081         value=$(cut -d= -f2 <<<$value)
11082         # LU-13168: truncated xattr should fail if short lov_user_md header
11083         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11084                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11085         for len in $lens; do
11086                 echo "setfattr $len $testfile.2"
11087                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11088                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11089         done
11090         local stripe_size=$($LFS getstripe -S $testfile.2)
11091         local stripe_count=$($LFS getstripe -c $testfile.2)
11092         [[ $stripe_size -eq 65536 ]] ||
11093                 error "stripe size $stripe_size != 65536"
11094         [[ $stripe_count -eq $stripe_count_orig ]] ||
11095                 error "stripe count $stripe_count != $stripe_count_orig"
11096         rm $testfile $testfile.2
11097 }
11098
11099 test_102b() {
11100         [ -z "$(which setfattr 2>/dev/null)" ] &&
11101                 skip_env "could not find setfattr"
11102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11103
11104         # check plain layout
11105         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11106
11107         # and also check composite layout
11108         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11109
11110 }
11111 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11112
11113 test_102c() {
11114         [ -z "$(which setfattr 2>/dev/null)" ] &&
11115                 skip_env "could not find setfattr"
11116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11117
11118         # b10930: get/set/list lustre.lov xattr
11119         echo "get/set/list lustre.lov xattr ..."
11120         test_mkdir $DIR/$tdir
11121         chown $RUNAS_ID $DIR/$tdir
11122         local testfile=$DIR/$tdir/$tfile
11123         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11124                 error "setstripe failed"
11125         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11126                 error "getstripe failed"
11127         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11128         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11129
11130         local testfile2=${testfile}2
11131         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11132                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11133
11134         $RUNAS $MCREATE $testfile2
11135         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11136         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11137         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11138         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11139         [ $stripe_count -eq $STRIPECOUNT ] ||
11140                 error "stripe count $stripe_count != $STRIPECOUNT"
11141 }
11142 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11143
11144 compare_stripe_info1() {
11145         local stripe_index_all_zero=true
11146
11147         for num in 1 2 3 4; do
11148                 for count in $(seq 1 $STRIPE_COUNT); do
11149                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11150                                 local size=$((STRIPE_SIZE * num))
11151                                 local file=file"$num-$offset-$count"
11152                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11153                                 [[ $stripe_size -ne $size ]] &&
11154                                     error "$file: size $stripe_size != $size"
11155                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11156                                 # allow fewer stripes to be created, ORI-601
11157                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11158                                     error "$file: count $stripe_count != $count"
11159                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11160                                 [[ $stripe_index -ne 0 ]] &&
11161                                         stripe_index_all_zero=false
11162                         done
11163                 done
11164         done
11165         $stripe_index_all_zero &&
11166                 error "all files are being extracted starting from OST index 0"
11167         return 0
11168 }
11169
11170 have_xattrs_include() {
11171         tar --help | grep -q xattrs-include &&
11172                 echo --xattrs-include="lustre.*"
11173 }
11174
11175 test_102d() {
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11178
11179         XINC=$(have_xattrs_include)
11180         setup_test102
11181         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11182         cd $DIR/$tdir/$tdir
11183         compare_stripe_info1
11184 }
11185 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11186
11187 test_102f() {
11188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11190
11191         XINC=$(have_xattrs_include)
11192         setup_test102
11193         test_mkdir $DIR/$tdir.restore
11194         cd $DIR
11195         tar cf - --xattrs $tdir | tar xf - \
11196                 -C $DIR/$tdir.restore --xattrs $XINC
11197         cd $DIR/$tdir.restore/$tdir
11198         compare_stripe_info1
11199 }
11200 run_test 102f "tar copy files, not keep osts"
11201
11202 grow_xattr() {
11203         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11204                 skip "must have user_xattr"
11205         [ -z "$(which setfattr 2>/dev/null)" ] &&
11206                 skip_env "could not find setfattr"
11207         [ -z "$(which getfattr 2>/dev/null)" ] &&
11208                 skip_env "could not find getfattr"
11209
11210         local xsize=${1:-1024}  # in bytes
11211         local file=$DIR/$tfile
11212         local value="$(generate_string $xsize)"
11213         local xbig=trusted.big
11214         local toobig=$2
11215
11216         touch $file
11217         log "save $xbig on $file"
11218         if [ -z "$toobig" ]
11219         then
11220                 setfattr -n $xbig -v $value $file ||
11221                         error "saving $xbig on $file failed"
11222         else
11223                 setfattr -n $xbig -v $value $file &&
11224                         error "saving $xbig on $file succeeded"
11225                 return 0
11226         fi
11227
11228         local orig=$(get_xattr_value $xbig $file)
11229         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11230
11231         local xsml=trusted.sml
11232         log "save $xsml on $file"
11233         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11234
11235         local new=$(get_xattr_value $xbig $file)
11236         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11237
11238         log "grow $xsml on $file"
11239         setfattr -n $xsml -v "$value" $file ||
11240                 error "growing $xsml on $file failed"
11241
11242         new=$(get_xattr_value $xbig $file)
11243         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11244         log "$xbig still valid after growing $xsml"
11245
11246         rm -f $file
11247 }
11248
11249 test_102h() { # bug 15777
11250         grow_xattr 1024
11251 }
11252 run_test 102h "grow xattr from inside inode to external block"
11253
11254 test_102ha() {
11255         large_xattr_enabled || skip_env "ea_inode feature disabled"
11256
11257         echo "setting xattr of max xattr size: $(max_xattr_size)"
11258         grow_xattr $(max_xattr_size)
11259
11260         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11261         echo "This should fail:"
11262         grow_xattr $(($(max_xattr_size) + 10)) 1
11263 }
11264 run_test 102ha "grow xattr from inside inode to external inode"
11265
11266 test_102i() { # bug 17038
11267         [ -z "$(which getfattr 2>/dev/null)" ] &&
11268                 skip "could not find getfattr"
11269
11270         touch $DIR/$tfile
11271         ln -s $DIR/$tfile $DIR/${tfile}link
11272         getfattr -n trusted.lov $DIR/$tfile ||
11273                 error "lgetxattr on $DIR/$tfile failed"
11274         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11275                 grep -i "no such attr" ||
11276                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11277         rm -f $DIR/$tfile $DIR/${tfile}link
11278 }
11279 run_test 102i "lgetxattr test on symbolic link ============"
11280
11281 test_102j() {
11282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11283         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11284
11285         XINC=$(have_xattrs_include)
11286         setup_test102 "$RUNAS"
11287         chown $RUNAS_ID $DIR/$tdir
11288         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11289         cd $DIR/$tdir/$tdir
11290         compare_stripe_info1 "$RUNAS"
11291 }
11292 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11293
11294 test_102k() {
11295         [ -z "$(which setfattr 2>/dev/null)" ] &&
11296                 skip "could not find setfattr"
11297
11298         touch $DIR/$tfile
11299         # b22187 just check that does not crash for regular file.
11300         setfattr -n trusted.lov $DIR/$tfile
11301         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11302         local test_kdir=$DIR/$tdir
11303         test_mkdir $test_kdir
11304         local default_size=$($LFS getstripe -S $test_kdir)
11305         local default_count=$($LFS getstripe -c $test_kdir)
11306         local default_offset=$($LFS getstripe -i $test_kdir)
11307         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11308                 error 'dir setstripe failed'
11309         setfattr -n trusted.lov $test_kdir
11310         local stripe_size=$($LFS getstripe -S $test_kdir)
11311         local stripe_count=$($LFS getstripe -c $test_kdir)
11312         local stripe_offset=$($LFS getstripe -i $test_kdir)
11313         [ $stripe_size -eq $default_size ] ||
11314                 error "stripe size $stripe_size != $default_size"
11315         [ $stripe_count -eq $default_count ] ||
11316                 error "stripe count $stripe_count != $default_count"
11317         [ $stripe_offset -eq $default_offset ] ||
11318                 error "stripe offset $stripe_offset != $default_offset"
11319         rm -rf $DIR/$tfile $test_kdir
11320 }
11321 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11322
11323 test_102l() {
11324         [ -z "$(which getfattr 2>/dev/null)" ] &&
11325                 skip "could not find getfattr"
11326
11327         # LU-532 trusted. xattr is invisible to non-root
11328         local testfile=$DIR/$tfile
11329
11330         touch $testfile
11331
11332         echo "listxattr as user..."
11333         chown $RUNAS_ID $testfile
11334         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11335             grep -q "trusted" &&
11336                 error "$testfile trusted xattrs are user visible"
11337
11338         return 0;
11339 }
11340 run_test 102l "listxattr size test =================================="
11341
11342 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11343         local path=$DIR/$tfile
11344         touch $path
11345
11346         listxattr_size_check $path || error "listattr_size_check $path failed"
11347 }
11348 run_test 102m "Ensure listxattr fails on small bufffer ========"
11349
11350 cleanup_test102
11351
11352 getxattr() { # getxattr path name
11353         # Return the base64 encoding of the value of xattr name on path.
11354         local path=$1
11355         local name=$2
11356
11357         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11358         # file: $path
11359         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11360         #
11361         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11362
11363         getfattr --absolute-names --encoding=base64 --name=$name $path |
11364                 awk -F= -v name=$name '$1 == name {
11365                         print substr($0, index($0, "=") + 1);
11366         }'
11367 }
11368
11369 test_102n() { # LU-4101 mdt: protect internal xattrs
11370         [ -z "$(which setfattr 2>/dev/null)" ] &&
11371                 skip "could not find setfattr"
11372         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11373         then
11374                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11375         fi
11376
11377         local file0=$DIR/$tfile.0
11378         local file1=$DIR/$tfile.1
11379         local xattr0=$TMP/$tfile.0
11380         local xattr1=$TMP/$tfile.1
11381         local namelist="lov lma lmv link fid version som hsm"
11382         local name
11383         local value
11384
11385         rm -rf $file0 $file1 $xattr0 $xattr1
11386         touch $file0 $file1
11387
11388         # Get 'before' xattrs of $file1.
11389         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11390
11391         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11392                 namelist+=" lfsck_namespace"
11393         for name in $namelist; do
11394                 # Try to copy xattr from $file0 to $file1.
11395                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11396
11397                 setfattr --name=trusted.$name --value="$value" $file1 ||
11398                         error "setxattr 'trusted.$name' failed"
11399
11400                 # Try to set a garbage xattr.
11401                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11402
11403                 if [[ x$name == "xlov" ]]; then
11404                         setfattr --name=trusted.lov --value="$value" $file1 &&
11405                         error "setxattr invalid 'trusted.lov' success"
11406                 else
11407                         setfattr --name=trusted.$name --value="$value" $file1 ||
11408                                 error "setxattr invalid 'trusted.$name' failed"
11409                 fi
11410
11411                 # Try to remove the xattr from $file1. We don't care if this
11412                 # appears to succeed or fail, we just don't want there to be
11413                 # any changes or crashes.
11414                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11415         done
11416
11417         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11418         then
11419                 name="lfsck_ns"
11420                 # Try to copy xattr from $file0 to $file1.
11421                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11422
11423                 setfattr --name=trusted.$name --value="$value" $file1 ||
11424                         error "setxattr 'trusted.$name' failed"
11425
11426                 # Try to set a garbage xattr.
11427                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11428
11429                 setfattr --name=trusted.$name --value="$value" $file1 ||
11430                         error "setxattr 'trusted.$name' failed"
11431
11432                 # Try to remove the xattr from $file1. We don't care if this
11433                 # appears to succeed or fail, we just don't want there to be
11434                 # any changes or crashes.
11435                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11436         fi
11437
11438         # Get 'after' xattrs of file1.
11439         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11440
11441         if ! diff $xattr0 $xattr1; then
11442                 error "before and after xattrs of '$file1' differ"
11443         fi
11444
11445         rm -rf $file0 $file1 $xattr0 $xattr1
11446
11447         return 0
11448 }
11449 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11450
11451 test_102p() { # LU-4703 setxattr did not check ownership
11452         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11453                 skip "MDS needs to be at least 2.5.56"
11454
11455         local testfile=$DIR/$tfile
11456
11457         touch $testfile
11458
11459         echo "setfacl as user..."
11460         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11461         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11462
11463         echo "setfattr as user..."
11464         setfacl -m "u:$RUNAS_ID:---" $testfile
11465         $RUNAS setfattr -x system.posix_acl_access $testfile
11466         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11467 }
11468 run_test 102p "check setxattr(2) correctly fails without permission"
11469
11470 test_102q() {
11471         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11472                 skip "MDS needs to be at least 2.6.92"
11473
11474         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11475 }
11476 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11477
11478 test_102r() {
11479         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11480                 skip "MDS needs to be at least 2.6.93"
11481
11482         touch $DIR/$tfile || error "touch"
11483         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11484         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11485         rm $DIR/$tfile || error "rm"
11486
11487         #normal directory
11488         mkdir -p $DIR/$tdir || error "mkdir"
11489         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11490         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11491         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11492                 error "$testfile error deleting user.author1"
11493         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11494                 grep "user.$(basename $tdir)" &&
11495                 error "$tdir did not delete user.$(basename $tdir)"
11496         rmdir $DIR/$tdir || error "rmdir"
11497
11498         #striped directory
11499         test_mkdir $DIR/$tdir
11500         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11501         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11502         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11503                 error "$testfile error deleting user.author1"
11504         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11505                 grep "user.$(basename $tdir)" &&
11506                 error "$tdir did not delete user.$(basename $tdir)"
11507         rmdir $DIR/$tdir || error "rm striped dir"
11508 }
11509 run_test 102r "set EAs with empty values"
11510
11511 test_102s() {
11512         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11513                 skip "MDS needs to be at least 2.11.52"
11514
11515         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11516
11517         save_lustre_params client "llite.*.xattr_cache" > $save
11518
11519         for cache in 0 1; do
11520                 lctl set_param llite.*.xattr_cache=$cache
11521
11522                 rm -f $DIR/$tfile
11523                 touch $DIR/$tfile || error "touch"
11524                 for prefix in lustre security system trusted user; do
11525                         # Note getxattr() may fail with 'Operation not
11526                         # supported' or 'No such attribute' depending
11527                         # on prefix and cache.
11528                         getfattr -n $prefix.n102s $DIR/$tfile &&
11529                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11530                 done
11531         done
11532
11533         restore_lustre_params < $save
11534 }
11535 run_test 102s "getting nonexistent xattrs should fail"
11536
11537 test_102t() {
11538         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11539                 skip "MDS needs to be at least 2.11.52"
11540
11541         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11542
11543         save_lustre_params client "llite.*.xattr_cache" > $save
11544
11545         for cache in 0 1; do
11546                 lctl set_param llite.*.xattr_cache=$cache
11547
11548                 for buf_size in 0 256; do
11549                         rm -f $DIR/$tfile
11550                         touch $DIR/$tfile || error "touch"
11551                         setfattr -n user.multiop $DIR/$tfile
11552                         $MULTIOP $DIR/$tfile oa$buf_size ||
11553                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11554                 done
11555         done
11556
11557         restore_lustre_params < $save
11558 }
11559 run_test 102t "zero length xattr values handled correctly"
11560
11561 run_acl_subtest()
11562 {
11563     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11564     return $?
11565 }
11566
11567 test_103a() {
11568         [ "$UID" != 0 ] && skip "must run as root"
11569         $GSS && skip_env "could not run under gss"
11570         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11571                 skip_env "must have acl enabled"
11572         [ -z "$(which setfacl 2>/dev/null)" ] &&
11573                 skip_env "could not find setfacl"
11574         remote_mds_nodsh && skip "remote MDS with nodsh"
11575
11576         gpasswd -a daemon bin                           # LU-5641
11577         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11578
11579         declare -a identity_old
11580
11581         for num in $(seq $MDSCOUNT); do
11582                 switch_identity $num true || identity_old[$num]=$?
11583         done
11584
11585         SAVE_UMASK=$(umask)
11586         umask 0022
11587         mkdir -p $DIR/$tdir
11588         cd $DIR/$tdir
11589
11590         echo "performing cp ..."
11591         run_acl_subtest cp || error "run_acl_subtest cp failed"
11592         echo "performing getfacl-noacl..."
11593         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11594         echo "performing misc..."
11595         run_acl_subtest misc || error  "misc test failed"
11596         echo "performing permissions..."
11597         run_acl_subtest permissions || error "permissions failed"
11598         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11599         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11600                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11601                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11602         then
11603                 echo "performing permissions xattr..."
11604                 run_acl_subtest permissions_xattr ||
11605                         error "permissions_xattr failed"
11606         fi
11607         echo "performing setfacl..."
11608         run_acl_subtest setfacl || error  "setfacl test failed"
11609
11610         # inheritance test got from HP
11611         echo "performing inheritance..."
11612         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11613         chmod +x make-tree || error "chmod +x failed"
11614         run_acl_subtest inheritance || error "inheritance test failed"
11615         rm -f make-tree
11616
11617         echo "LU-974 ignore umask when acl is enabled..."
11618         run_acl_subtest 974 || error "LU-974 umask test failed"
11619         if [ $MDSCOUNT -ge 2 ]; then
11620                 run_acl_subtest 974_remote ||
11621                         error "LU-974 umask test failed under remote dir"
11622         fi
11623
11624         echo "LU-2561 newly created file is same size as directory..."
11625         if [ "$mds1_FSTYPE" != "zfs" ]; then
11626                 run_acl_subtest 2561 || error "LU-2561 test failed"
11627         else
11628                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11629         fi
11630
11631         run_acl_subtest 4924 || error "LU-4924 test failed"
11632
11633         cd $SAVE_PWD
11634         umask $SAVE_UMASK
11635
11636         for num in $(seq $MDSCOUNT); do
11637                 if [ "${identity_old[$num]}" = 1 ]; then
11638                         switch_identity $num false || identity_old[$num]=$?
11639                 fi
11640         done
11641 }
11642 run_test 103a "acl test"
11643
11644 test_103b() {
11645         declare -a pids
11646         local U
11647
11648         for U in {0..511}; do
11649                 {
11650                 local O=$(printf "%04o" $U)
11651
11652                 umask $(printf "%04o" $((511 ^ $O)))
11653                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11654                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11655
11656                 (( $S == ($O & 0666) )) ||
11657                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11658
11659                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11660                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11661                 (( $S == ($O & 0666) )) ||
11662                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11663
11664                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11665                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11666                 (( $S == ($O & 0666) )) ||
11667                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11668                 rm -f $DIR/$tfile.[smp]$0
11669                 } &
11670                 local pid=$!
11671
11672                 # limit the concurrently running threads to 64. LU-11878
11673                 local idx=$((U % 64))
11674                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11675                 pids[idx]=$pid
11676         done
11677         wait
11678 }
11679 run_test 103b "umask lfs setstripe"
11680
11681 test_103c() {
11682         mkdir -p $DIR/$tdir
11683         cp -rp $DIR/$tdir $DIR/$tdir.bak
11684
11685         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11686                 error "$DIR/$tdir shouldn't contain default ACL"
11687         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11688                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11689         true
11690 }
11691 run_test 103c "'cp -rp' won't set empty acl"
11692
11693 test_103e() {
11694         local numacl
11695         local fileacl
11696         local saved_debug=$($LCTL get_param -n debug)
11697
11698         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11699                 skip "MDS needs to be at least 2.14.52"
11700
11701         large_xattr_enabled || skip_env "ea_inode feature disabled"
11702
11703         mkdir -p $DIR/$tdir
11704         # add big LOV EA to cause reply buffer overflow earlier
11705         $LFS setstripe -C 1000 $DIR/$tdir
11706         lctl set_param mdc.*-mdc*.stats=clear
11707
11708         $LCTL set_param debug=0
11709         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11710         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11711
11712         # add a large number of default ACLs (expect 8000+ for 2.13+)
11713         for U in {2..7000}; do
11714                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11715                         error "Able to add just $U default ACLs"
11716         done
11717         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11718         echo "$numacl default ACLs created"
11719
11720         stat $DIR/$tdir || error "Cannot stat directory"
11721         # check file creation
11722         touch $DIR/$tdir/$tfile ||
11723                 error "failed to create $tfile with $numacl default ACLs"
11724         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11725         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11726         echo "$fileacl ACLs were inherited"
11727         (( $fileacl == $numacl )) ||
11728                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11729         # check that new ACLs creation adds new ACLs to inherited ACLs
11730         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11731                 error "Cannot set new ACL"
11732         numacl=$((numacl + 1))
11733         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11734         (( $fileacl == $numacl )) ||
11735                 error "failed to add new ACL: $fileacl != $numacl as expected"
11736         # adds more ACLs to a file to reach their maximum at 8000+
11737         numacl=0
11738         for U in {20000..25000}; do
11739                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11740                 numacl=$((numacl + 1))
11741         done
11742         echo "Added $numacl more ACLs to the file"
11743         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11744         echo "Total $fileacl ACLs in file"
11745         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11746         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11747         rmdir $DIR/$tdir || error "Cannot remove directory"
11748 }
11749 run_test 103e "inheritance of big amount of default ACLs"
11750
11751 test_103f() {
11752         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11753                 skip "MDS needs to be at least 2.14.51"
11754
11755         large_xattr_enabled || skip_env "ea_inode feature disabled"
11756
11757         # enable changelog to consume more internal MDD buffers
11758         changelog_register
11759
11760         mkdir -p $DIR/$tdir
11761         # add big LOV EA
11762         $LFS setstripe -C 1000 $DIR/$tdir
11763         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11764         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11765         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11766         rmdir $DIR/$tdir || error "Cannot remove directory"
11767 }
11768 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11769
11770 test_104a() {
11771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11772
11773         touch $DIR/$tfile
11774         lfs df || error "lfs df failed"
11775         lfs df -ih || error "lfs df -ih failed"
11776         lfs df -h $DIR || error "lfs df -h $DIR failed"
11777         lfs df -i $DIR || error "lfs df -i $DIR failed"
11778         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11779         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11780
11781         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11782         lctl --device %$OSC deactivate
11783         lfs df || error "lfs df with deactivated OSC failed"
11784         lctl --device %$OSC activate
11785         # wait the osc back to normal
11786         wait_osc_import_ready client ost
11787
11788         lfs df || error "lfs df with reactivated OSC failed"
11789         rm -f $DIR/$tfile
11790 }
11791 run_test 104a "lfs df [-ih] [path] test ========================="
11792
11793 test_104b() {
11794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11795         [ $RUNAS_ID -eq $UID ] &&
11796                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11797
11798         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11799                         grep "Permission denied" | wc -l)))
11800         if [ $denied_cnt -ne 0 ]; then
11801                 error "lfs check servers test failed"
11802         fi
11803 }
11804 run_test 104b "$RUNAS lfs check servers test ===================="
11805
11806 #
11807 # Verify $1 is within range of $2.
11808 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11809 # $1 is <= 2% of $2. Else Fail.
11810 #
11811 value_in_range() {
11812         # Strip all units (M, G, T)
11813         actual=$(echo $1 | tr -d A-Z)
11814         expect=$(echo $2 | tr -d A-Z)
11815
11816         expect_lo=$(($expect * 98 / 100)) # 2% below
11817         expect_hi=$(($expect * 102 / 100)) # 2% above
11818
11819         # permit 2% drift above and below
11820         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11821 }
11822
11823 test_104c() {
11824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11825         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11826
11827         local ost_param="osd-zfs.$FSNAME-OST0000."
11828         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11829         local ofacets=$(get_facets OST)
11830         local mfacets=$(get_facets MDS)
11831         local saved_ost_blocks=
11832         local saved_mdt_blocks=
11833
11834         echo "Before recordsize change"
11835         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11836         df=($(df -h | grep "$MOUNT"$))
11837
11838         # For checking.
11839         echo "lfs output : ${lfs_df[*]}"
11840         echo "df  output : ${df[*]}"
11841
11842         for facet in ${ofacets//,/ }; do
11843                 if [ -z $saved_ost_blocks ]; then
11844                         saved_ost_blocks=$(do_facet $facet \
11845                                 lctl get_param -n $ost_param.blocksize)
11846                         echo "OST Blocksize: $saved_ost_blocks"
11847                 fi
11848                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11849                 do_facet $facet zfs set recordsize=32768 $ost
11850         done
11851
11852         # BS too small. Sufficient for functional testing.
11853         for facet in ${mfacets//,/ }; do
11854                 if [ -z $saved_mdt_blocks ]; then
11855                         saved_mdt_blocks=$(do_facet $facet \
11856                                 lctl get_param -n $mdt_param.blocksize)
11857                         echo "MDT Blocksize: $saved_mdt_blocks"
11858                 fi
11859                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11860                 do_facet $facet zfs set recordsize=32768 $mdt
11861         done
11862
11863         # Give new values chance to reflect change
11864         sleep 2
11865
11866         echo "After recordsize change"
11867         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11868         df_after=($(df -h | grep "$MOUNT"$))
11869
11870         # For checking.
11871         echo "lfs output : ${lfs_df_after[*]}"
11872         echo "df  output : ${df_after[*]}"
11873
11874         # Verify lfs df
11875         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11876                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11877         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11878                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11879         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11880                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11881
11882         # Verify df
11883         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11884                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11885         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11886                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11887         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11888                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11889
11890         # Restore MDT recordize back to original
11891         for facet in ${mfacets//,/ }; do
11892                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11893                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11894         done
11895
11896         # Restore OST recordize back to original
11897         for facet in ${ofacets//,/ }; do
11898                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11899                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11900         done
11901
11902         return 0
11903 }
11904 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11905
11906 test_105a() {
11907         # doesn't work on 2.4 kernels
11908         touch $DIR/$tfile
11909         if $(flock_is_enabled); then
11910                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11911         else
11912                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11913         fi
11914         rm -f $DIR/$tfile
11915 }
11916 run_test 105a "flock when mounted without -o flock test ========"
11917
11918 test_105b() {
11919         touch $DIR/$tfile
11920         if $(flock_is_enabled); then
11921                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11922         else
11923                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11924         fi
11925         rm -f $DIR/$tfile
11926 }
11927 run_test 105b "fcntl when mounted without -o flock test ========"
11928
11929 test_105c() {
11930         touch $DIR/$tfile
11931         if $(flock_is_enabled); then
11932                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11933         else
11934                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11935         fi
11936         rm -f $DIR/$tfile
11937 }
11938 run_test 105c "lockf when mounted without -o flock test"
11939
11940 test_105d() { # bug 15924
11941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11942
11943         test_mkdir $DIR/$tdir
11944         flock_is_enabled || skip_env "mount w/o flock enabled"
11945         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11946         $LCTL set_param fail_loc=0x80000315
11947         flocks_test 2 $DIR/$tdir
11948 }
11949 run_test 105d "flock race (should not freeze) ========"
11950
11951 test_105e() { # bug 22660 && 22040
11952         flock_is_enabled || skip_env "mount w/o flock enabled"
11953
11954         touch $DIR/$tfile
11955         flocks_test 3 $DIR/$tfile
11956 }
11957 run_test 105e "Two conflicting flocks from same process"
11958
11959 test_106() { #bug 10921
11960         test_mkdir $DIR/$tdir
11961         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11962         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11963 }
11964 run_test 106 "attempt exec of dir followed by chown of that dir"
11965
11966 test_107() {
11967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11968
11969         CDIR=`pwd`
11970         local file=core
11971
11972         cd $DIR
11973         rm -f $file
11974
11975         local save_pattern=$(sysctl -n kernel.core_pattern)
11976         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11977         sysctl -w kernel.core_pattern=$file
11978         sysctl -w kernel.core_uses_pid=0
11979
11980         ulimit -c unlimited
11981         sleep 60 &
11982         SLEEPPID=$!
11983
11984         sleep 1
11985
11986         kill -s 11 $SLEEPPID
11987         wait $SLEEPPID
11988         if [ -e $file ]; then
11989                 size=`stat -c%s $file`
11990                 [ $size -eq 0 ] && error "Fail to create core file $file"
11991         else
11992                 error "Fail to create core file $file"
11993         fi
11994         rm -f $file
11995         sysctl -w kernel.core_pattern=$save_pattern
11996         sysctl -w kernel.core_uses_pid=$save_uses_pid
11997         cd $CDIR
11998 }
11999 run_test 107 "Coredump on SIG"
12000
12001 test_110() {
12002         test_mkdir $DIR/$tdir
12003         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12004         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12005                 error "mkdir with 256 char should fail, but did not"
12006         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12007                 error "create with 255 char failed"
12008         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12009                 error "create with 256 char should fail, but did not"
12010
12011         ls -l $DIR/$tdir
12012         rm -rf $DIR/$tdir
12013 }
12014 run_test 110 "filename length checking"
12015
12016 #
12017 # Purpose: To verify dynamic thread (OSS) creation.
12018 #
12019 test_115() {
12020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12021         remote_ost_nodsh && skip "remote OST with nodsh"
12022
12023         # Lustre does not stop service threads once they are started.
12024         # Reset number of running threads to default.
12025         stopall
12026         setupall
12027
12028         local OSTIO_pre
12029         local save_params="$TMP/sanity-$TESTNAME.parameters"
12030
12031         # Get ll_ost_io count before I/O
12032         OSTIO_pre=$(do_facet ost1 \
12033                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12034         # Exit if lustre is not running (ll_ost_io not running).
12035         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12036
12037         echo "Starting with $OSTIO_pre threads"
12038         local thread_max=$((OSTIO_pre * 2))
12039         local rpc_in_flight=$((thread_max * 2))
12040         # this is limited to OSC_MAX_RIF_MAX (256)
12041         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12042         thread_max=$((rpc_in_flight / 2))
12043         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12044                 return
12045
12046         # Number of I/O Process proposed to be started.
12047         local nfiles
12048         local facets=$(get_facets OST)
12049
12050         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12051         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12052
12053         # Set in_flight to $rpc_in_flight
12054         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12055                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12056         nfiles=${rpc_in_flight}
12057         # Set ost thread_max to $thread_max
12058         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12059
12060         # 5 Minutes should be sufficient for max number of OSS
12061         # threads(thread_max) to be created.
12062         local timeout=300
12063
12064         # Start I/O.
12065         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12066         test_mkdir $DIR/$tdir
12067         for i in $(seq $nfiles); do
12068                 local file=$DIR/$tdir/${tfile}-$i
12069                 $LFS setstripe -c -1 -i 0 $file
12070                 ($WTL $file $timeout)&
12071         done
12072
12073         # I/O Started - Wait for thread_started to reach thread_max or report
12074         # error if thread_started is more than thread_max.
12075         echo "Waiting for thread_started to reach thread_max"
12076         local thread_started=0
12077         local end_time=$((SECONDS + timeout))
12078
12079         while [ $SECONDS -le $end_time ] ; do
12080                 echo -n "."
12081                 # Get ost i/o thread_started count.
12082                 thread_started=$(do_facet ost1 \
12083                         "$LCTL get_param \
12084                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12085                 # Break out if thread_started is equal/greater than thread_max
12086                 if [[ $thread_started -ge $thread_max ]]; then
12087                         echo ll_ost_io thread_started $thread_started, \
12088                                 equal/greater than thread_max $thread_max
12089                         break
12090                 fi
12091                 sleep 1
12092         done
12093
12094         # Cleanup - We have the numbers, Kill i/o jobs if running.
12095         jobcount=($(jobs -p))
12096         for i in $(seq 0 $((${#jobcount[@]}-1)))
12097         do
12098                 kill -9 ${jobcount[$i]}
12099                 if [ $? -ne 0 ] ; then
12100                         echo Warning: \
12101                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12102                 fi
12103         done
12104
12105         # Cleanup files left by WTL binary.
12106         for i in $(seq $nfiles); do
12107                 local file=$DIR/$tdir/${tfile}-$i
12108                 rm -rf $file
12109                 if [ $? -ne 0 ] ; then
12110                         echo "Warning: Failed to delete file $file"
12111                 fi
12112         done
12113
12114         restore_lustre_params <$save_params
12115         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12116
12117         # Error out if no new thread has started or Thread started is greater
12118         # than thread max.
12119         if [[ $thread_started -le $OSTIO_pre ||
12120                         $thread_started -gt $thread_max ]]; then
12121                 error "ll_ost_io: thread_started $thread_started" \
12122                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12123                       "No new thread started or thread started greater " \
12124                       "than thread_max."
12125         fi
12126 }
12127 run_test 115 "verify dynamic thread creation===================="
12128
12129 test_116a() { # was previously test_116()
12130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12132         remote_mds_nodsh && skip "remote MDS with nodsh"
12133
12134         echo -n "Free space priority "
12135         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12136                 head -n1
12137         declare -a AVAIL
12138         free_min_max
12139
12140         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12141         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12142         stack_trap simple_cleanup_common
12143
12144         # Check if we need to generate uneven OSTs
12145         test_mkdir -p $DIR/$tdir/OST${MINI}
12146         local FILL=$((MINV / 4))
12147         local DIFF=$((MAXV - MINV))
12148         local DIFF2=$((DIFF * 100 / MINV))
12149
12150         local threshold=$(do_facet $SINGLEMDS \
12151                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12152         threshold=${threshold%%%}
12153         echo -n "Check for uneven OSTs: "
12154         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12155
12156         if [[ $DIFF2 -gt $threshold ]]; then
12157                 echo "ok"
12158                 echo "Don't need to fill OST$MINI"
12159         else
12160                 # generate uneven OSTs. Write 2% over the QOS threshold value
12161                 echo "no"
12162                 DIFF=$((threshold - DIFF2 + 2))
12163                 DIFF2=$((MINV * DIFF / 100))
12164                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12165                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12166                         error "setstripe failed"
12167                 DIFF=$((DIFF2 / 2048))
12168                 i=0
12169                 while [ $i -lt $DIFF ]; do
12170                         i=$((i + 1))
12171                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12172                                 bs=2M count=1 2>/dev/null
12173                         echo -n .
12174                 done
12175                 echo .
12176                 sync
12177                 sleep_maxage
12178                 free_min_max
12179         fi
12180
12181         DIFF=$((MAXV - MINV))
12182         DIFF2=$((DIFF * 100 / MINV))
12183         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12184         if [ $DIFF2 -gt $threshold ]; then
12185                 echo "ok"
12186         else
12187                 skip "QOS imbalance criteria not met"
12188         fi
12189
12190         MINI1=$MINI
12191         MINV1=$MINV
12192         MAXI1=$MAXI
12193         MAXV1=$MAXV
12194
12195         # now fill using QOS
12196         $LFS setstripe -c 1 $DIR/$tdir
12197         FILL=$((FILL / 200))
12198         if [ $FILL -gt 600 ]; then
12199                 FILL=600
12200         fi
12201         echo "writing $FILL files to QOS-assigned OSTs"
12202         i=0
12203         while [ $i -lt $FILL ]; do
12204                 i=$((i + 1))
12205                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12206                         count=1 2>/dev/null
12207                 echo -n .
12208         done
12209         echo "wrote $i 200k files"
12210         sync
12211         sleep_maxage
12212
12213         echo "Note: free space may not be updated, so measurements might be off"
12214         free_min_max
12215         DIFF2=$((MAXV - MINV))
12216         echo "free space delta: orig $DIFF final $DIFF2"
12217         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12218         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12219         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12220         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12221         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12222         if [[ $DIFF -gt 0 ]]; then
12223                 FILL=$((DIFF2 * 100 / DIFF - 100))
12224                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12225         fi
12226
12227         # Figure out which files were written where
12228         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12229                awk '/'$MINI1': / {print $2; exit}')
12230         echo $UUID
12231         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12232         echo "$MINC files created on smaller OST $MINI1"
12233         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12234                awk '/'$MAXI1': / {print $2; exit}')
12235         echo $UUID
12236         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12237         echo "$MAXC files created on larger OST $MAXI1"
12238         if [[ $MINC -gt 0 ]]; then
12239                 FILL=$((MAXC * 100 / MINC - 100))
12240                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12241         fi
12242         [[ $MAXC -gt $MINC ]] ||
12243                 error_ignore LU-9 "stripe QOS didn't balance free space"
12244 }
12245 run_test 116a "stripe QOS: free space balance ==================="
12246
12247 test_116b() { # LU-2093
12248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12249         remote_mds_nodsh && skip "remote MDS with nodsh"
12250
12251 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12252         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12253                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12254         [ -z "$old_rr" ] && skip "no QOS"
12255         do_facet $SINGLEMDS lctl set_param \
12256                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12257         mkdir -p $DIR/$tdir
12258         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12259         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12260         do_facet $SINGLEMDS lctl set_param fail_loc=0
12261         rm -rf $DIR/$tdir
12262         do_facet $SINGLEMDS lctl set_param \
12263                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12264 }
12265 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12266
12267 test_117() # bug 10891
12268 {
12269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12270
12271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12272         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12273         lctl set_param fail_loc=0x21e
12274         > $DIR/$tfile || error "truncate failed"
12275         lctl set_param fail_loc=0
12276         echo "Truncate succeeded."
12277         rm -f $DIR/$tfile
12278 }
12279 run_test 117 "verify osd extend =========="
12280
12281 NO_SLOW_RESENDCOUNT=4
12282 export OLD_RESENDCOUNT=""
12283 set_resend_count () {
12284         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12285         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12286         lctl set_param -n $PROC_RESENDCOUNT $1
12287         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12288 }
12289
12290 # for reduce test_118* time (b=14842)
12291 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12292
12293 # Reset async IO behavior after error case
12294 reset_async() {
12295         FILE=$DIR/reset_async
12296
12297         # Ensure all OSCs are cleared
12298         $LFS setstripe -c -1 $FILE
12299         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12300         sync
12301         rm $FILE
12302 }
12303
12304 test_118a() #bug 11710
12305 {
12306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12307
12308         reset_async
12309
12310         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12311         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12312         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12313
12314         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12315                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12316                 return 1;
12317         fi
12318         rm -f $DIR/$tfile
12319 }
12320 run_test 118a "verify O_SYNC works =========="
12321
12322 test_118b()
12323 {
12324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12325         remote_ost_nodsh && skip "remote OST with nodsh"
12326
12327         reset_async
12328
12329         #define OBD_FAIL_SRV_ENOENT 0x217
12330         set_nodes_failloc "$(osts_nodes)" 0x217
12331         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12332         RC=$?
12333         set_nodes_failloc "$(osts_nodes)" 0
12334         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12335         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12336                     grep -c writeback)
12337
12338         if [[ $RC -eq 0 ]]; then
12339                 error "Must return error due to dropped pages, rc=$RC"
12340                 return 1;
12341         fi
12342
12343         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12344                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12345                 return 1;
12346         fi
12347
12348         echo "Dirty pages not leaked on ENOENT"
12349
12350         # Due to the above error the OSC will issue all RPCs syncronously
12351         # until a subsequent RPC completes successfully without error.
12352         $MULTIOP $DIR/$tfile Ow4096yc
12353         rm -f $DIR/$tfile
12354
12355         return 0
12356 }
12357 run_test 118b "Reclaim dirty pages on fatal error =========="
12358
12359 test_118c()
12360 {
12361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12362
12363         # for 118c, restore the original resend count, LU-1940
12364         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12365                                 set_resend_count $OLD_RESENDCOUNT
12366         remote_ost_nodsh && skip "remote OST with nodsh"
12367
12368         reset_async
12369
12370         #define OBD_FAIL_OST_EROFS               0x216
12371         set_nodes_failloc "$(osts_nodes)" 0x216
12372
12373         # multiop should block due to fsync until pages are written
12374         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12375         MULTIPID=$!
12376         sleep 1
12377
12378         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12379                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12380         fi
12381
12382         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12383                     grep -c writeback)
12384         if [[ $WRITEBACK -eq 0 ]]; then
12385                 error "No page in writeback, writeback=$WRITEBACK"
12386         fi
12387
12388         set_nodes_failloc "$(osts_nodes)" 0
12389         wait $MULTIPID
12390         RC=$?
12391         if [[ $RC -ne 0 ]]; then
12392                 error "Multiop fsync failed, rc=$RC"
12393         fi
12394
12395         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12396         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12397                     grep -c writeback)
12398         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12399                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12400         fi
12401
12402         rm -f $DIR/$tfile
12403         echo "Dirty pages flushed via fsync on EROFS"
12404         return 0
12405 }
12406 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12407
12408 # continue to use small resend count to reduce test_118* time (b=14842)
12409 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12410
12411 test_118d()
12412 {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414         remote_ost_nodsh && skip "remote OST with nodsh"
12415
12416         reset_async
12417
12418         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12419         set_nodes_failloc "$(osts_nodes)" 0x214
12420         # multiop should block due to fsync until pages are written
12421         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12422         MULTIPID=$!
12423         sleep 1
12424
12425         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12426                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12427         fi
12428
12429         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12430                     grep -c writeback)
12431         if [[ $WRITEBACK -eq 0 ]]; then
12432                 error "No page in writeback, writeback=$WRITEBACK"
12433         fi
12434
12435         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12436         set_nodes_failloc "$(osts_nodes)" 0
12437
12438         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12439         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12440                     grep -c writeback)
12441         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12442                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12443         fi
12444
12445         rm -f $DIR/$tfile
12446         echo "Dirty pages gaurenteed flushed via fsync"
12447         return 0
12448 }
12449 run_test 118d "Fsync validation inject a delay of the bulk =========="
12450
12451 test_118f() {
12452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12453
12454         reset_async
12455
12456         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12457         lctl set_param fail_loc=0x8000040a
12458
12459         # Should simulate EINVAL error which is fatal
12460         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12461         RC=$?
12462         if [[ $RC -eq 0 ]]; then
12463                 error "Must return error due to dropped pages, rc=$RC"
12464         fi
12465
12466         lctl set_param fail_loc=0x0
12467
12468         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12469         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12470         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12471                     grep -c writeback)
12472         if [[ $LOCKED -ne 0 ]]; then
12473                 error "Locked pages remain in cache, locked=$LOCKED"
12474         fi
12475
12476         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12477                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12478         fi
12479
12480         rm -f $DIR/$tfile
12481         echo "No pages locked after fsync"
12482
12483         reset_async
12484         return 0
12485 }
12486 run_test 118f "Simulate unrecoverable OSC side error =========="
12487
12488 test_118g() {
12489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12490
12491         reset_async
12492
12493         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12494         lctl set_param fail_loc=0x406
12495
12496         # simulate local -ENOMEM
12497         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12498         RC=$?
12499
12500         lctl set_param fail_loc=0
12501         if [[ $RC -eq 0 ]]; then
12502                 error "Must return error due to dropped pages, rc=$RC"
12503         fi
12504
12505         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12506         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12507         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12508                         grep -c writeback)
12509         if [[ $LOCKED -ne 0 ]]; then
12510                 error "Locked pages remain in cache, locked=$LOCKED"
12511         fi
12512
12513         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12514                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12515         fi
12516
12517         rm -f $DIR/$tfile
12518         echo "No pages locked after fsync"
12519
12520         reset_async
12521         return 0
12522 }
12523 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12524
12525 test_118h() {
12526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12527         remote_ost_nodsh && skip "remote OST with nodsh"
12528
12529         reset_async
12530
12531         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12532         set_nodes_failloc "$(osts_nodes)" 0x20e
12533         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12534         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12535         RC=$?
12536
12537         set_nodes_failloc "$(osts_nodes)" 0
12538         if [[ $RC -eq 0 ]]; then
12539                 error "Must return error due to dropped pages, rc=$RC"
12540         fi
12541
12542         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12543         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12544         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12545                     grep -c writeback)
12546         if [[ $LOCKED -ne 0 ]]; then
12547                 error "Locked pages remain in cache, locked=$LOCKED"
12548         fi
12549
12550         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12551                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12552         fi
12553
12554         rm -f $DIR/$tfile
12555         echo "No pages locked after fsync"
12556
12557         return 0
12558 }
12559 run_test 118h "Verify timeout in handling recoverables errors  =========="
12560
12561 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12562
12563 test_118i() {
12564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12565         remote_ost_nodsh && skip "remote OST with nodsh"
12566
12567         reset_async
12568
12569         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12570         set_nodes_failloc "$(osts_nodes)" 0x20e
12571
12572         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12573         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12574         PID=$!
12575         sleep 5
12576         set_nodes_failloc "$(osts_nodes)" 0
12577
12578         wait $PID
12579         RC=$?
12580         if [[ $RC -ne 0 ]]; then
12581                 error "got error, but should be not, rc=$RC"
12582         fi
12583
12584         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12585         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12586         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12587         if [[ $LOCKED -ne 0 ]]; then
12588                 error "Locked pages remain in cache, locked=$LOCKED"
12589         fi
12590
12591         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12592                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12593         fi
12594
12595         rm -f $DIR/$tfile
12596         echo "No pages locked after fsync"
12597
12598         return 0
12599 }
12600 run_test 118i "Fix error before timeout in recoverable error  =========="
12601
12602 [ "$SLOW" = "no" ] && set_resend_count 4
12603
12604 test_118j() {
12605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12606         remote_ost_nodsh && skip "remote OST with nodsh"
12607
12608         reset_async
12609
12610         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12611         set_nodes_failloc "$(osts_nodes)" 0x220
12612
12613         # return -EIO from OST
12614         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12615         RC=$?
12616         set_nodes_failloc "$(osts_nodes)" 0x0
12617         if [[ $RC -eq 0 ]]; then
12618                 error "Must return error due to dropped pages, rc=$RC"
12619         fi
12620
12621         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12622         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12623         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12624         if [[ $LOCKED -ne 0 ]]; then
12625                 error "Locked pages remain in cache, locked=$LOCKED"
12626         fi
12627
12628         # in recoverable error on OST we want resend and stay until it finished
12629         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12630                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12631         fi
12632
12633         rm -f $DIR/$tfile
12634         echo "No pages locked after fsync"
12635
12636         return 0
12637 }
12638 run_test 118j "Simulate unrecoverable OST side error =========="
12639
12640 test_118k()
12641 {
12642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12643         remote_ost_nodsh && skip "remote OSTs with nodsh"
12644
12645         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12646         set_nodes_failloc "$(osts_nodes)" 0x20e
12647         test_mkdir $DIR/$tdir
12648
12649         for ((i=0;i<10;i++)); do
12650                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12651                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12652                 SLEEPPID=$!
12653                 sleep 0.500s
12654                 kill $SLEEPPID
12655                 wait $SLEEPPID
12656         done
12657
12658         set_nodes_failloc "$(osts_nodes)" 0
12659         rm -rf $DIR/$tdir
12660 }
12661 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12662
12663 test_118l() # LU-646
12664 {
12665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12666
12667         test_mkdir $DIR/$tdir
12668         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12669         rm -rf $DIR/$tdir
12670 }
12671 run_test 118l "fsync dir"
12672
12673 test_118m() # LU-3066
12674 {
12675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12676
12677         test_mkdir $DIR/$tdir
12678         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12679         rm -rf $DIR/$tdir
12680 }
12681 run_test 118m "fdatasync dir ========="
12682
12683 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12684
12685 test_118n()
12686 {
12687         local begin
12688         local end
12689
12690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12691         remote_ost_nodsh && skip "remote OSTs with nodsh"
12692
12693         # Sleep to avoid a cached response.
12694         #define OBD_STATFS_CACHE_SECONDS 1
12695         sleep 2
12696
12697         # Inject a 10 second delay in the OST_STATFS handler.
12698         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12699         set_nodes_failloc "$(osts_nodes)" 0x242
12700
12701         begin=$SECONDS
12702         stat --file-system $MOUNT > /dev/null
12703         end=$SECONDS
12704
12705         set_nodes_failloc "$(osts_nodes)" 0
12706
12707         if ((end - begin > 20)); then
12708             error "statfs took $((end - begin)) seconds, expected 10"
12709         fi
12710 }
12711 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12712
12713 test_119a() # bug 11737
12714 {
12715         BSIZE=$((512 * 1024))
12716         directio write $DIR/$tfile 0 1 $BSIZE
12717         # We ask to read two blocks, which is more than a file size.
12718         # directio will indicate an error when requested and actual
12719         # sizes aren't equeal (a normal situation in this case) and
12720         # print actual read amount.
12721         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12722         if [ "$NOB" != "$BSIZE" ]; then
12723                 error "read $NOB bytes instead of $BSIZE"
12724         fi
12725         rm -f $DIR/$tfile
12726 }
12727 run_test 119a "Short directIO read must return actual read amount"
12728
12729 test_119b() # bug 11737
12730 {
12731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12732
12733         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12735         sync
12736         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12737                 error "direct read failed"
12738         rm -f $DIR/$tfile
12739 }
12740 run_test 119b "Sparse directIO read must return actual read amount"
12741
12742 test_119c() # bug 13099
12743 {
12744         BSIZE=1048576
12745         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12746         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12747         rm -f $DIR/$tfile
12748 }
12749 run_test 119c "Testing for direct read hitting hole"
12750
12751 test_119d() # bug 15950
12752 {
12753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12754
12755         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12756         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12757         BSIZE=1048576
12758         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12759         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12760         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12761         lctl set_param fail_loc=0x40d
12762         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12763         pid_dio=$!
12764         sleep 1
12765         cat $DIR/$tfile > /dev/null &
12766         lctl set_param fail_loc=0
12767         pid_reads=$!
12768         wait $pid_dio
12769         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12770         sleep 2
12771         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12772         error "the read rpcs have not completed in 2s"
12773         rm -f $DIR/$tfile
12774         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12775 }
12776 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12777
12778 test_120a() {
12779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12780         remote_mds_nodsh && skip "remote MDS with nodsh"
12781         test_mkdir -i0 -c1 $DIR/$tdir
12782         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12783                 skip_env "no early lock cancel on server"
12784
12785         lru_resize_disable mdc
12786         lru_resize_disable osc
12787         cancel_lru_locks mdc
12788         # asynchronous object destroy at MDT could cause bl ast to client
12789         cancel_lru_locks osc
12790
12791         stat $DIR/$tdir > /dev/null
12792         can1=$(do_facet mds1 \
12793                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12794                awk '/ldlm_cancel/ {print $2}')
12795         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12796                awk '/ldlm_bl_callback/ {print $2}')
12797         test_mkdir -i0 -c1 $DIR/$tdir/d1
12798         can2=$(do_facet mds1 \
12799                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12800                awk '/ldlm_cancel/ {print $2}')
12801         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12802                awk '/ldlm_bl_callback/ {print $2}')
12803         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12804         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12805         lru_resize_enable mdc
12806         lru_resize_enable osc
12807 }
12808 run_test 120a "Early Lock Cancel: mkdir test"
12809
12810 test_120b() {
12811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12812         remote_mds_nodsh && skip "remote MDS with nodsh"
12813         test_mkdir $DIR/$tdir
12814         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12815                 skip_env "no early lock cancel on server"
12816
12817         lru_resize_disable mdc
12818         lru_resize_disable osc
12819         cancel_lru_locks mdc
12820         stat $DIR/$tdir > /dev/null
12821         can1=$(do_facet $SINGLEMDS \
12822                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12823                awk '/ldlm_cancel/ {print $2}')
12824         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12825                awk '/ldlm_bl_callback/ {print $2}')
12826         touch $DIR/$tdir/f1
12827         can2=$(do_facet $SINGLEMDS \
12828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12829                awk '/ldlm_cancel/ {print $2}')
12830         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12831                awk '/ldlm_bl_callback/ {print $2}')
12832         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12833         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12834         lru_resize_enable mdc
12835         lru_resize_enable osc
12836 }
12837 run_test 120b "Early Lock Cancel: create test"
12838
12839 test_120c() {
12840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12841         remote_mds_nodsh && skip "remote MDS with nodsh"
12842         test_mkdir -i0 -c1 $DIR/$tdir
12843         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12844                 skip "no early lock cancel on server"
12845
12846         lru_resize_disable mdc
12847         lru_resize_disable osc
12848         test_mkdir -i0 -c1 $DIR/$tdir/d1
12849         test_mkdir -i0 -c1 $DIR/$tdir/d2
12850         touch $DIR/$tdir/d1/f1
12851         cancel_lru_locks mdc
12852         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12853         can1=$(do_facet mds1 \
12854                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12855                awk '/ldlm_cancel/ {print $2}')
12856         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12857                awk '/ldlm_bl_callback/ {print $2}')
12858         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12859         can2=$(do_facet mds1 \
12860                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12861                awk '/ldlm_cancel/ {print $2}')
12862         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12863                awk '/ldlm_bl_callback/ {print $2}')
12864         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12865         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12866         lru_resize_enable mdc
12867         lru_resize_enable osc
12868 }
12869 run_test 120c "Early Lock Cancel: link test"
12870
12871 test_120d() {
12872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12873         remote_mds_nodsh && skip "remote MDS with nodsh"
12874         test_mkdir -i0 -c1 $DIR/$tdir
12875         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12876                 skip_env "no early lock cancel on server"
12877
12878         lru_resize_disable mdc
12879         lru_resize_disable osc
12880         touch $DIR/$tdir
12881         cancel_lru_locks mdc
12882         stat $DIR/$tdir > /dev/null
12883         can1=$(do_facet mds1 \
12884                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12885                awk '/ldlm_cancel/ {print $2}')
12886         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12887                awk '/ldlm_bl_callback/ {print $2}')
12888         chmod a+x $DIR/$tdir
12889         can2=$(do_facet mds1 \
12890                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12891                awk '/ldlm_cancel/ {print $2}')
12892         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12893                awk '/ldlm_bl_callback/ {print $2}')
12894         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12895         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12896         lru_resize_enable mdc
12897         lru_resize_enable osc
12898 }
12899 run_test 120d "Early Lock Cancel: setattr test"
12900
12901 test_120e() {
12902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12903         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12904                 skip_env "no early lock cancel on server"
12905         remote_mds_nodsh && skip "remote MDS with nodsh"
12906
12907         local dlmtrace_set=false
12908
12909         test_mkdir -i0 -c1 $DIR/$tdir
12910         lru_resize_disable mdc
12911         lru_resize_disable osc
12912         ! $LCTL get_param debug | grep -q dlmtrace &&
12913                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12914         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12915         cancel_lru_locks mdc
12916         cancel_lru_locks osc
12917         dd if=$DIR/$tdir/f1 of=/dev/null
12918         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12919         # XXX client can not do early lock cancel of OST lock
12920         # during unlink (LU-4206), so cancel osc lock now.
12921         sleep 2
12922         cancel_lru_locks osc
12923         can1=$(do_facet mds1 \
12924                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12925                awk '/ldlm_cancel/ {print $2}')
12926         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12927                awk '/ldlm_bl_callback/ {print $2}')
12928         unlink $DIR/$tdir/f1
12929         sleep 5
12930         can2=$(do_facet mds1 \
12931                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12932                awk '/ldlm_cancel/ {print $2}')
12933         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12934                awk '/ldlm_bl_callback/ {print $2}')
12935         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12936                 $LCTL dk $TMP/cancel.debug.txt
12937         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12938                 $LCTL dk $TMP/blocking.debug.txt
12939         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12940         lru_resize_enable mdc
12941         lru_resize_enable osc
12942 }
12943 run_test 120e "Early Lock Cancel: unlink test"
12944
12945 test_120f() {
12946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12947         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12948                 skip_env "no early lock cancel on server"
12949         remote_mds_nodsh && skip "remote MDS with nodsh"
12950
12951         test_mkdir -i0 -c1 $DIR/$tdir
12952         lru_resize_disable mdc
12953         lru_resize_disable osc
12954         test_mkdir -i0 -c1 $DIR/$tdir/d1
12955         test_mkdir -i0 -c1 $DIR/$tdir/d2
12956         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12957         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12958         cancel_lru_locks mdc
12959         cancel_lru_locks osc
12960         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12961         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12962         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12963         # XXX client can not do early lock cancel of OST lock
12964         # during rename (LU-4206), so cancel osc lock now.
12965         sleep 2
12966         cancel_lru_locks osc
12967         can1=$(do_facet mds1 \
12968                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12969                awk '/ldlm_cancel/ {print $2}')
12970         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12971                awk '/ldlm_bl_callback/ {print $2}')
12972         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12973         sleep 5
12974         can2=$(do_facet mds1 \
12975                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12976                awk '/ldlm_cancel/ {print $2}')
12977         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12978                awk '/ldlm_bl_callback/ {print $2}')
12979         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12980         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12981         lru_resize_enable mdc
12982         lru_resize_enable osc
12983 }
12984 run_test 120f "Early Lock Cancel: rename test"
12985
12986 test_120g() {
12987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12988         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12989                 skip_env "no early lock cancel on server"
12990         remote_mds_nodsh && skip "remote MDS with nodsh"
12991
12992         lru_resize_disable mdc
12993         lru_resize_disable osc
12994         count=10000
12995         echo create $count files
12996         test_mkdir $DIR/$tdir
12997         cancel_lru_locks mdc
12998         cancel_lru_locks osc
12999         t0=$(date +%s)
13000
13001         can0=$(do_facet $SINGLEMDS \
13002                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13003                awk '/ldlm_cancel/ {print $2}')
13004         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13005                awk '/ldlm_bl_callback/ {print $2}')
13006         createmany -o $DIR/$tdir/f $count
13007         sync
13008         can1=$(do_facet $SINGLEMDS \
13009                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13010                awk '/ldlm_cancel/ {print $2}')
13011         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13012                awk '/ldlm_bl_callback/ {print $2}')
13013         t1=$(date +%s)
13014         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13015         echo rm $count files
13016         rm -r $DIR/$tdir
13017         sync
13018         can2=$(do_facet $SINGLEMDS \
13019                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13020                awk '/ldlm_cancel/ {print $2}')
13021         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13022                awk '/ldlm_bl_callback/ {print $2}')
13023         t2=$(date +%s)
13024         echo total: $count removes in $((t2-t1))
13025         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13026         sleep 2
13027         # wait for commitment of removal
13028         lru_resize_enable mdc
13029         lru_resize_enable osc
13030 }
13031 run_test 120g "Early Lock Cancel: performance test"
13032
13033 test_121() { #bug #10589
13034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13035
13036         rm -rf $DIR/$tfile
13037         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13038 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13039         lctl set_param fail_loc=0x310
13040         cancel_lru_locks osc > /dev/null
13041         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13042         lctl set_param fail_loc=0
13043         [[ $reads -eq $writes ]] ||
13044                 error "read $reads blocks, must be $writes blocks"
13045 }
13046 run_test 121 "read cancel race ========="
13047
13048 test_123a_base() { # was test 123, statahead(bug 11401)
13049         local lsx="$1"
13050
13051         SLOWOK=0
13052         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13053                 log "testing UP system. Performance may be lower than expected."
13054                 SLOWOK=1
13055         fi
13056         running_in_vm && SLOWOK=1
13057
13058         rm -rf $DIR/$tdir
13059         test_mkdir $DIR/$tdir
13060         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13061         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13062         MULT=10
13063         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13064                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13065
13066                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13067                 lctl set_param -n llite.*.statahead_max 0
13068                 lctl get_param llite.*.statahead_max
13069                 cancel_lru_locks mdc
13070                 cancel_lru_locks osc
13071                 stime=$(date +%s)
13072                 time $lsx $DIR/$tdir | wc -l
13073                 etime=$(date +%s)
13074                 delta=$((etime - stime))
13075                 log "$lsx $i files without statahead: $delta sec"
13076                 lctl set_param llite.*.statahead_max=$max
13077
13078                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13079                          awk '/statahead.wrong:/ { print $NF }')
13080                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13081                 cancel_lru_locks mdc
13082                 cancel_lru_locks osc
13083                 stime=$(date +%s)
13084                 time $lsx $DIR/$tdir | wc -l
13085                 etime=$(date +%s)
13086                 delta_sa=$((etime - stime))
13087                 log "$lsx $i files with statahead: $delta_sa sec"
13088                 lctl get_param -n llite.*.statahead_stats
13089                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13090                          awk '/statahead.wrong:/ { print $NF }')
13091
13092                 [[ $swrong -lt $ewrong ]] &&
13093                         log "statahead was stopped, maybe too many locks held!"
13094                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13095
13096                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13097                         max=$(lctl get_param -n llite.*.statahead_max |
13098                                 head -n 1)
13099                         lctl set_param -n llite.*.statahead_max 0
13100                         lctl get_param llite.*.statahead_max
13101                         cancel_lru_locks mdc
13102                         cancel_lru_locks osc
13103                         stime=$(date +%s)
13104                         time $lsx $DIR/$tdir | wc -l
13105                         etime=$(date +%s)
13106                         delta=$((etime - stime))
13107                         log "$lsx $i files again without statahead: $delta sec"
13108                         lctl set_param llite.*.statahead_max=$max
13109                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13110                                 if [ $SLOWOK -eq 0 ]; then
13111                                         error "$lsx $i files is slower with statahead!"
13112                                 else
13113                                         log "$lsx $i files is slower with statahead!"
13114                                 fi
13115                                 break
13116                         fi
13117                 fi
13118
13119                 [ $delta -gt 20 ] && break
13120                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13121                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13122         done
13123         log "$lsx done"
13124
13125         stime=$(date +%s)
13126         rm -r $DIR/$tdir
13127         sync
13128         etime=$(date +%s)
13129         delta=$((etime - stime))
13130         log "rm -r $DIR/$tdir/: $delta seconds"
13131         log "rm done"
13132         lctl get_param -n llite.*.statahead_stats
13133 }
13134
13135 test_123aa() {
13136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13137
13138         test_123a_base "ls -l"
13139 }
13140 run_test 123aa "verify statahead work"
13141
13142 test_123ab() {
13143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13144
13145         statx_supported || skip_env "Test must be statx() syscall supported"
13146
13147         test_123a_base "$STATX -l"
13148 }
13149 run_test 123ab "verify statahead work by using statx"
13150
13151 test_123ac() {
13152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13153
13154         statx_supported || skip_env "Test must be statx() syscall supported"
13155
13156         local rpcs_before
13157         local rpcs_after
13158         local agl_before
13159         local agl_after
13160
13161         cancel_lru_locks $OSC
13162         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13163         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13164                      awk '/agl.total:/ { print $NF }')
13165         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13166         test_123a_base "$STATX --cached=always -D"
13167         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13168                     awk '/agl.total:/ { print $NF }')
13169         [ $agl_before -eq $agl_after ] ||
13170                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13171         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13172         [ $rpcs_after -eq $rpcs_before ] ||
13173                 error "$STATX should not send glimpse RPCs to $OSC"
13174 }
13175 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13176
13177 test_123b () { # statahead(bug 15027)
13178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13179
13180         test_mkdir $DIR/$tdir
13181         createmany -o $DIR/$tdir/$tfile-%d 1000
13182
13183         cancel_lru_locks mdc
13184         cancel_lru_locks osc
13185
13186 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13187         lctl set_param fail_loc=0x80000803
13188         ls -lR $DIR/$tdir > /dev/null
13189         log "ls done"
13190         lctl set_param fail_loc=0x0
13191         lctl get_param -n llite.*.statahead_stats
13192         rm -r $DIR/$tdir
13193         sync
13194
13195 }
13196 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13197
13198 test_123c() {
13199         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13200
13201         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13202         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13203         touch $DIR/$tdir.1/{1..3}
13204         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13205
13206         remount_client $MOUNT
13207
13208         $MULTIOP $DIR/$tdir.0 Q
13209
13210         # let statahead to complete
13211         ls -l $DIR/$tdir.0 > /dev/null
13212
13213         testid=$(echo $TESTNAME | tr '_' ' ')
13214         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13215                 error "statahead warning" || true
13216 }
13217 run_test 123c "Can not initialize inode warning on DNE statahead"
13218
13219 test_123d() {
13220         local num=100
13221         local swrong
13222         local ewrong
13223
13224         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13225         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13226                 error "setdirstripe $DIR/$tdir failed"
13227         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13228         remount_client $MOUNT
13229         $LCTL get_param llite.*.statahead_max
13230         $LCTL set_param llite.*.statahead_stats=0 ||
13231                 error "clear statahead_stats failed"
13232         swrong=$(lctl get_param -n llite.*.statahead_stats |
13233                  awk '/statahead.wrong:/ { print $NF }')
13234         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13235         # wait for statahead thread finished to update hit/miss stats.
13236         sleep 1
13237         $LCTL get_param -n llite.*.statahead_stats
13238         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13239                  awk '/statahead.wrong:/ { print $NF }')
13240         (( $swrong == $ewrong )) ||
13241                 log "statahead was stopped, maybe too many locks held!"
13242 }
13243 run_test 123d "Statahead on striped directories works correctly"
13244
13245 test_124a() {
13246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13247         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13248                 skip_env "no lru resize on server"
13249
13250         local NR=2000
13251
13252         test_mkdir $DIR/$tdir
13253
13254         log "create $NR files at $DIR/$tdir"
13255         createmany -o $DIR/$tdir/f $NR ||
13256                 error "failed to create $NR files in $DIR/$tdir"
13257
13258         cancel_lru_locks mdc
13259         ls -l $DIR/$tdir > /dev/null
13260
13261         local NSDIR=""
13262         local LRU_SIZE=0
13263         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13264                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13265                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13266                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13267                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13268                         log "NSDIR=$NSDIR"
13269                         log "NS=$(basename $NSDIR)"
13270                         break
13271                 fi
13272         done
13273
13274         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13275                 skip "Not enough cached locks created!"
13276         fi
13277         log "LRU=$LRU_SIZE"
13278
13279         local SLEEP=30
13280
13281         # We know that lru resize allows one client to hold $LIMIT locks
13282         # for 10h. After that locks begin to be killed by client.
13283         local MAX_HRS=10
13284         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13285         log "LIMIT=$LIMIT"
13286         if [ $LIMIT -lt $LRU_SIZE ]; then
13287                 skip "Limit is too small $LIMIT"
13288         fi
13289
13290         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13291         # killing locks. Some time was spent for creating locks. This means
13292         # that up to the moment of sleep finish we must have killed some of
13293         # them (10-100 locks). This depends on how fast ther were created.
13294         # Many of them were touched in almost the same moment and thus will
13295         # be killed in groups.
13296         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13297
13298         # Use $LRU_SIZE_B here to take into account real number of locks
13299         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13300         local LRU_SIZE_B=$LRU_SIZE
13301         log "LVF=$LVF"
13302         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13303         log "OLD_LVF=$OLD_LVF"
13304         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13305
13306         # Let's make sure that we really have some margin. Client checks
13307         # cached locks every 10 sec.
13308         SLEEP=$((SLEEP+20))
13309         log "Sleep ${SLEEP} sec"
13310         local SEC=0
13311         while ((SEC<$SLEEP)); do
13312                 echo -n "..."
13313                 sleep 5
13314                 SEC=$((SEC+5))
13315                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13316                 echo -n "$LRU_SIZE"
13317         done
13318         echo ""
13319         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13320         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13321
13322         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13323                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13324                 unlinkmany $DIR/$tdir/f $NR
13325                 return
13326         }
13327
13328         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13329         log "unlink $NR files at $DIR/$tdir"
13330         unlinkmany $DIR/$tdir/f $NR
13331 }
13332 run_test 124a "lru resize ======================================="
13333
13334 get_max_pool_limit()
13335 {
13336         local limit=$($LCTL get_param \
13337                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13338         local max=0
13339         for l in $limit; do
13340                 if [[ $l -gt $max ]]; then
13341                         max=$l
13342                 fi
13343         done
13344         echo $max
13345 }
13346
13347 test_124b() {
13348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13349         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13350                 skip_env "no lru resize on server"
13351
13352         LIMIT=$(get_max_pool_limit)
13353
13354         NR=$(($(default_lru_size)*20))
13355         if [[ $NR -gt $LIMIT ]]; then
13356                 log "Limit lock number by $LIMIT locks"
13357                 NR=$LIMIT
13358         fi
13359
13360         IFree=$(mdsrate_inodes_available)
13361         if [ $IFree -lt $NR ]; then
13362                 log "Limit lock number by $IFree inodes"
13363                 NR=$IFree
13364         fi
13365
13366         lru_resize_disable mdc
13367         test_mkdir -p $DIR/$tdir/disable_lru_resize
13368
13369         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13370         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13371         cancel_lru_locks mdc
13372         stime=`date +%s`
13373         PID=""
13374         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13375         PID="$PID $!"
13376         sleep 2
13377         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13378         PID="$PID $!"
13379         sleep 2
13380         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13381         PID="$PID $!"
13382         wait $PID
13383         etime=`date +%s`
13384         nolruresize_delta=$((etime-stime))
13385         log "ls -la time: $nolruresize_delta seconds"
13386         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13387         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13388
13389         lru_resize_enable mdc
13390         test_mkdir -p $DIR/$tdir/enable_lru_resize
13391
13392         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13393         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13394         cancel_lru_locks mdc
13395         stime=`date +%s`
13396         PID=""
13397         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13398         PID="$PID $!"
13399         sleep 2
13400         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13401         PID="$PID $!"
13402         sleep 2
13403         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13404         PID="$PID $!"
13405         wait $PID
13406         etime=`date +%s`
13407         lruresize_delta=$((etime-stime))
13408         log "ls -la time: $lruresize_delta seconds"
13409         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13410
13411         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13412                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13413         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13414                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13415         else
13416                 log "lru resize performs the same with no lru resize"
13417         fi
13418         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13419 }
13420 run_test 124b "lru resize (performance test) ======================="
13421
13422 test_124c() {
13423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13424         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13425                 skip_env "no lru resize on server"
13426
13427         # cache ununsed locks on client
13428         local nr=100
13429         cancel_lru_locks mdc
13430         test_mkdir $DIR/$tdir
13431         createmany -o $DIR/$tdir/f $nr ||
13432                 error "failed to create $nr files in $DIR/$tdir"
13433         ls -l $DIR/$tdir > /dev/null
13434
13435         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13436         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13437         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13438         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13439         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13440
13441         # set lru_max_age to 1 sec
13442         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13443         echo "sleep $((recalc_p * 2)) seconds..."
13444         sleep $((recalc_p * 2))
13445
13446         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13447         # restore lru_max_age
13448         $LCTL set_param -n $nsdir.lru_max_age $max_age
13449         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13450         unlinkmany $DIR/$tdir/f $nr
13451 }
13452 run_test 124c "LRUR cancel very aged locks"
13453
13454 test_124d() {
13455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13456         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13457                 skip_env "no lru resize on server"
13458
13459         # cache ununsed locks on client
13460         local nr=100
13461
13462         lru_resize_disable mdc
13463         stack_trap "lru_resize_enable mdc" EXIT
13464
13465         cancel_lru_locks mdc
13466
13467         # asynchronous object destroy at MDT could cause bl ast to client
13468         test_mkdir $DIR/$tdir
13469         createmany -o $DIR/$tdir/f $nr ||
13470                 error "failed to create $nr files in $DIR/$tdir"
13471         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13472
13473         ls -l $DIR/$tdir > /dev/null
13474
13475         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13476         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13477         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13478         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13479
13480         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13481
13482         # set lru_max_age to 1 sec
13483         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13484         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13485
13486         echo "sleep $((recalc_p * 2)) seconds..."
13487         sleep $((recalc_p * 2))
13488
13489         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13490
13491         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13492 }
13493 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13494
13495 test_125() { # 13358
13496         $LCTL get_param -n llite.*.client_type | grep -q local ||
13497                 skip "must run as local client"
13498         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13499                 skip_env "must have acl enabled"
13500         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13501
13502         test_mkdir $DIR/$tdir
13503         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13504         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13505         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13506 }
13507 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13508
13509 test_126() { # bug 12829/13455
13510         $GSS && skip_env "must run as gss disabled"
13511         $LCTL get_param -n llite.*.client_type | grep -q local ||
13512                 skip "must run as local client"
13513         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13514
13515         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13516         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13517         rm -f $DIR/$tfile
13518         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13519 }
13520 run_test 126 "check that the fsgid provided by the client is taken into account"
13521
13522 test_127a() { # bug 15521
13523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13524         local name count samp unit min max sum sumsq
13525
13526         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13527         echo "stats before reset"
13528         $LCTL get_param osc.*.stats
13529         $LCTL set_param osc.*.stats=0
13530         local fsize=$((2048 * 1024))
13531
13532         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13533         cancel_lru_locks osc
13534         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13535
13536         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13537         stack_trap "rm -f $TMP/$tfile.tmp"
13538         while read name count samp unit min max sum sumsq; do
13539                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13540                 [ ! $min ] && error "Missing min value for $name proc entry"
13541                 eval $name=$count || error "Wrong proc format"
13542
13543                 case $name in
13544                 read_bytes|write_bytes)
13545                         [[ "$unit" =~ "bytes" ]] ||
13546                                 error "unit is not 'bytes': $unit"
13547                         (( $min >= 4096 )) || error "min is too small: $min"
13548                         (( $min <= $fsize )) || error "min is too big: $min"
13549                         (( $max >= 4096 )) || error "max is too small: $max"
13550                         (( $max <= $fsize )) || error "max is too big: $max"
13551                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13552                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13553                                 error "sumsquare is too small: $sumsq"
13554                         (( $sumsq <= $fsize * $fsize )) ||
13555                                 error "sumsquare is too big: $sumsq"
13556                         ;;
13557                 ost_read|ost_write)
13558                         [[ "$unit" =~ "usec" ]] ||
13559                                 error "unit is not 'usec': $unit"
13560                         ;;
13561                 *)      ;;
13562                 esac
13563         done < $DIR/$tfile.tmp
13564
13565         #check that we actually got some stats
13566         [ "$read_bytes" ] || error "Missing read_bytes stats"
13567         [ "$write_bytes" ] || error "Missing write_bytes stats"
13568         [ "$read_bytes" != 0 ] || error "no read done"
13569         [ "$write_bytes" != 0 ] || error "no write done"
13570 }
13571 run_test 127a "verify the client stats are sane"
13572
13573 test_127b() { # bug LU-333
13574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13575         local name count samp unit min max sum sumsq
13576
13577         echo "stats before reset"
13578         $LCTL get_param llite.*.stats
13579         $LCTL set_param llite.*.stats=0
13580
13581         # perform 2 reads and writes so MAX is different from SUM.
13582         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13583         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13584         cancel_lru_locks osc
13585         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13586         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13587
13588         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13589         stack_trap "rm -f $TMP/$tfile.tmp"
13590         while read name count samp unit min max sum sumsq; do
13591                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13592                 eval $name=$count || error "Wrong proc format"
13593
13594                 case $name in
13595                 read_bytes|write_bytes)
13596                         [[ "$unit" =~ "bytes" ]] ||
13597                                 error "unit is not 'bytes': $unit"
13598                         (( $count == 2 )) || error "count is not 2: $count"
13599                         (( $min == $PAGE_SIZE )) ||
13600                                 error "min is not $PAGE_SIZE: $min"
13601                         (( $max == $PAGE_SIZE )) ||
13602                                 error "max is not $PAGE_SIZE: $max"
13603                         (( $sum == $PAGE_SIZE * 2 )) ||
13604                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13605                         ;;
13606                 read|write)
13607                         [[ "$unit" =~ "usec" ]] ||
13608                                 error "unit is not 'usec': $unit"
13609                         ;;
13610                 *)      ;;
13611                 esac
13612         done < $TMP/$tfile.tmp
13613
13614         #check that we actually got some stats
13615         [ "$read_bytes" ] || error "Missing read_bytes stats"
13616         [ "$write_bytes" ] || error "Missing write_bytes stats"
13617         [ "$read_bytes" != 0 ] || error "no read done"
13618         [ "$write_bytes" != 0 ] || error "no write done"
13619 }
13620 run_test 127b "verify the llite client stats are sane"
13621
13622 test_127c() { # LU-12394
13623         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13624         local size
13625         local bsize
13626         local reads
13627         local writes
13628         local count
13629
13630         $LCTL set_param llite.*.extents_stats=1
13631         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13632
13633         # Use two stripes so there is enough space in default config
13634         $LFS setstripe -c 2 $DIR/$tfile
13635
13636         # Extent stats start at 0-4K and go in power of two buckets
13637         # LL_HIST_START = 12 --> 2^12 = 4K
13638         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13639         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13640         # small configs
13641         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13642                 do
13643                 # Write and read, 2x each, second time at a non-zero offset
13644                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13645                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13646                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13647                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13648                 rm -f $DIR/$tfile
13649         done
13650
13651         $LCTL get_param llite.*.extents_stats
13652
13653         count=2
13654         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13655                 do
13656                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13657                                 grep -m 1 $bsize)
13658                 reads=$(echo $bucket | awk '{print $5}')
13659                 writes=$(echo $bucket | awk '{print $9}')
13660                 [ "$reads" -eq $count ] ||
13661                         error "$reads reads in < $bsize bucket, expect $count"
13662                 [ "$writes" -eq $count ] ||
13663                         error "$writes writes in < $bsize bucket, expect $count"
13664         done
13665
13666         # Test mmap write and read
13667         $LCTL set_param llite.*.extents_stats=c
13668         size=512
13669         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13670         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13671         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13672
13673         $LCTL get_param llite.*.extents_stats
13674
13675         count=$(((size*1024) / PAGE_SIZE))
13676
13677         bsize=$((2 * PAGE_SIZE / 1024))K
13678
13679         bucket=$($LCTL get_param -n llite.*.extents_stats |
13680                         grep -m 1 $bsize)
13681         reads=$(echo $bucket | awk '{print $5}')
13682         writes=$(echo $bucket | awk '{print $9}')
13683         # mmap writes fault in the page first, creating an additonal read
13684         [ "$reads" -eq $((2 * count)) ] ||
13685                 error "$reads reads in < $bsize bucket, expect $count"
13686         [ "$writes" -eq $count ] ||
13687                 error "$writes writes in < $bsize bucket, expect $count"
13688 }
13689 run_test 127c "test llite extent stats with regular & mmap i/o"
13690
13691 test_128() { # bug 15212
13692         touch $DIR/$tfile
13693         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13694                 find $DIR/$tfile
13695                 find $DIR/$tfile
13696         EOF
13697
13698         result=$(grep error $TMP/$tfile.log)
13699         rm -f $DIR/$tfile $TMP/$tfile.log
13700         [ -z "$result" ] ||
13701                 error "consecutive find's under interactive lfs failed"
13702 }
13703 run_test 128 "interactive lfs for 2 consecutive find's"
13704
13705 set_dir_limits () {
13706         local mntdev
13707         local canondev
13708         local node
13709
13710         local ldproc=/proc/fs/ldiskfs
13711         local facets=$(get_facets MDS)
13712
13713         for facet in ${facets//,/ }; do
13714                 canondev=$(ldiskfs_canon \
13715                            *.$(convert_facet2label $facet).mntdev $facet)
13716                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13717                         ldproc=/sys/fs/ldiskfs
13718                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13719                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13720         done
13721 }
13722
13723 check_mds_dmesg() {
13724         local facets=$(get_facets MDS)
13725         for facet in ${facets//,/ }; do
13726                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13727         done
13728         return 1
13729 }
13730
13731 test_129() {
13732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13733         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13734                 skip "Need MDS version with at least 2.5.56"
13735         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13736                 skip_env "ldiskfs only test"
13737         fi
13738         remote_mds_nodsh && skip "remote MDS with nodsh"
13739
13740         local ENOSPC=28
13741         local has_warning=false
13742
13743         rm -rf $DIR/$tdir
13744         mkdir -p $DIR/$tdir
13745
13746         # block size of mds1
13747         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13748         set_dir_limits $maxsize $((maxsize * 6 / 8))
13749         stack_trap "set_dir_limits 0 0"
13750         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13751         local dirsize=$(stat -c%s "$DIR/$tdir")
13752         local nfiles=0
13753         while (( $dirsize <= $maxsize )); do
13754                 $MCREATE $DIR/$tdir/file_base_$nfiles
13755                 rc=$?
13756                 # check two errors:
13757                 # ENOSPC for ext4 max_dir_size, which has been used since
13758                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13759                 if (( rc == ENOSPC )); then
13760                         set_dir_limits 0 0
13761                         echo "rc=$rc returned as expected after $nfiles files"
13762
13763                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13764                                 error "create failed w/o dir size limit"
13765
13766                         # messages may be rate limited if test is run repeatedly
13767                         check_mds_dmesg '"is approaching max"' ||
13768                                 echo "warning message should be output"
13769                         check_mds_dmesg '"has reached max"' ||
13770                                 echo "reached message should be output"
13771
13772                         dirsize=$(stat -c%s "$DIR/$tdir")
13773
13774                         [[ $dirsize -ge $maxsize ]] && return 0
13775                         error "dirsize $dirsize < $maxsize after $nfiles files"
13776                 elif (( rc != 0 )); then
13777                         break
13778                 fi
13779                 nfiles=$((nfiles + 1))
13780                 dirsize=$(stat -c%s "$DIR/$tdir")
13781         done
13782
13783         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13784 }
13785 run_test 129 "test directory size limit ========================"
13786
13787 OLDIFS="$IFS"
13788 cleanup_130() {
13789         trap 0
13790         IFS="$OLDIFS"
13791 }
13792
13793 test_130a() {
13794         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13795         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13796
13797         trap cleanup_130 EXIT RETURN
13798
13799         local fm_file=$DIR/$tfile
13800         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13801         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13802                 error "dd failed for $fm_file"
13803
13804         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13805         filefrag -ves $fm_file
13806         RC=$?
13807         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13808                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13809         [ $RC != 0 ] && error "filefrag $fm_file failed"
13810
13811         filefrag_op=$(filefrag -ve -k $fm_file |
13812                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13813         lun=$($LFS getstripe -i $fm_file)
13814
13815         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13816         IFS=$'\n'
13817         tot_len=0
13818         for line in $filefrag_op
13819         do
13820                 frag_lun=`echo $line | cut -d: -f5`
13821                 ext_len=`echo $line | cut -d: -f4`
13822                 if (( $frag_lun != $lun )); then
13823                         cleanup_130
13824                         error "FIEMAP on 1-stripe file($fm_file) failed"
13825                         return
13826                 fi
13827                 (( tot_len += ext_len ))
13828         done
13829
13830         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13831                 cleanup_130
13832                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13833                 return
13834         fi
13835
13836         cleanup_130
13837
13838         echo "FIEMAP on single striped file succeeded"
13839 }
13840 run_test 130a "FIEMAP (1-stripe file)"
13841
13842 test_130b() {
13843         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13844
13845         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13846         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13847
13848         trap cleanup_130 EXIT RETURN
13849
13850         local fm_file=$DIR/$tfile
13851         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13852                         error "setstripe on $fm_file"
13853         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13854                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13855
13856         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13857                 error "dd failed on $fm_file"
13858
13859         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13860         filefrag_op=$(filefrag -ve -k $fm_file |
13861                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13862
13863         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13864                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13865
13866         IFS=$'\n'
13867         tot_len=0
13868         num_luns=1
13869         for line in $filefrag_op
13870         do
13871                 frag_lun=$(echo $line | cut -d: -f5 |
13872                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13873                 ext_len=$(echo $line | cut -d: -f4)
13874                 if (( $frag_lun != $last_lun )); then
13875                         if (( tot_len != 1024 )); then
13876                                 cleanup_130
13877                                 error "FIEMAP on $fm_file failed; returned " \
13878                                 "len $tot_len for OST $last_lun instead of 1024"
13879                                 return
13880                         else
13881                                 (( num_luns += 1 ))
13882                                 tot_len=0
13883                         fi
13884                 fi
13885                 (( tot_len += ext_len ))
13886                 last_lun=$frag_lun
13887         done
13888         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13889                 cleanup_130
13890                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13891                         "luns or wrong len for OST $last_lun"
13892                 return
13893         fi
13894
13895         cleanup_130
13896
13897         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13898 }
13899 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13900
13901 test_130c() {
13902         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13903
13904         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13905         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13906
13907         trap cleanup_130 EXIT RETURN
13908
13909         local fm_file=$DIR/$tfile
13910         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13911         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13912                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13913
13914         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13915                         error "dd failed on $fm_file"
13916
13917         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13918         filefrag_op=$(filefrag -ve -k $fm_file |
13919                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13920
13921         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13922                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13923
13924         IFS=$'\n'
13925         tot_len=0
13926         num_luns=1
13927         for line in $filefrag_op
13928         do
13929                 frag_lun=$(echo $line | cut -d: -f5 |
13930                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13931                 ext_len=$(echo $line | cut -d: -f4)
13932                 if (( $frag_lun != $last_lun )); then
13933                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13934                         if (( logical != 512 )); then
13935                                 cleanup_130
13936                                 error "FIEMAP on $fm_file failed; returned " \
13937                                 "logical start for lun $logical instead of 512"
13938                                 return
13939                         fi
13940                         if (( tot_len != 512 )); then
13941                                 cleanup_130
13942                                 error "FIEMAP on $fm_file failed; returned " \
13943                                 "len $tot_len for OST $last_lun instead of 1024"
13944                                 return
13945                         else
13946                                 (( num_luns += 1 ))
13947                                 tot_len=0
13948                         fi
13949                 fi
13950                 (( tot_len += ext_len ))
13951                 last_lun=$frag_lun
13952         done
13953         if (( num_luns != 2 || tot_len != 512 )); then
13954                 cleanup_130
13955                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13956                         "luns or wrong len for OST $last_lun"
13957                 return
13958         fi
13959
13960         cleanup_130
13961
13962         echo "FIEMAP on 2-stripe file with hole succeeded"
13963 }
13964 run_test 130c "FIEMAP (2-stripe file with hole)"
13965
13966 test_130d() {
13967         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13968
13969         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13970         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13971
13972         trap cleanup_130 EXIT RETURN
13973
13974         local fm_file=$DIR/$tfile
13975         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13976                         error "setstripe on $fm_file"
13977         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13978                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13979
13980         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13981         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13982                 error "dd failed on $fm_file"
13983
13984         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13985         filefrag_op=$(filefrag -ve -k $fm_file |
13986                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13987
13988         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13989                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13990
13991         IFS=$'\n'
13992         tot_len=0
13993         num_luns=1
13994         for line in $filefrag_op
13995         do
13996                 frag_lun=$(echo $line | cut -d: -f5 |
13997                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13998                 ext_len=$(echo $line | cut -d: -f4)
13999                 if (( $frag_lun != $last_lun )); then
14000                         if (( tot_len != 1024 )); then
14001                                 cleanup_130
14002                                 error "FIEMAP on $fm_file failed; returned " \
14003                                 "len $tot_len for OST $last_lun instead of 1024"
14004                                 return
14005                         else
14006                                 (( num_luns += 1 ))
14007                                 tot_len=0
14008                         fi
14009                 fi
14010                 (( tot_len += ext_len ))
14011                 last_lun=$frag_lun
14012         done
14013         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14014                 cleanup_130
14015                 error "FIEMAP on $fm_file failed; returned wrong number of " \
14016                         "luns or wrong len for OST $last_lun"
14017                 return
14018         fi
14019
14020         cleanup_130
14021
14022         echo "FIEMAP on N-stripe file succeeded"
14023 }
14024 run_test 130d "FIEMAP (N-stripe file)"
14025
14026 test_130e() {
14027         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
14028
14029         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14030         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
14031
14032         trap cleanup_130 EXIT RETURN
14033
14034         local fm_file=$DIR/$tfile
14035         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14036
14037         NUM_BLKS=512
14038         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
14039         for ((i = 0; i < $NUM_BLKS; i++)); do
14040                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14041                         conv=notrunc > /dev/null 2>&1
14042         done
14043
14044         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14045         filefrag_op=$(filefrag -ve -k $fm_file |
14046                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14047
14048         last_lun=$(echo $filefrag_op | cut -d: -f5)
14049
14050         IFS=$'\n'
14051         tot_len=0
14052         num_luns=1
14053         for line in $filefrag_op; do
14054                 frag_lun=$(echo $line | cut -d: -f5)
14055                 ext_len=$(echo $line | cut -d: -f4)
14056                 if [[ "$frag_lun" != "$last_lun" ]]; then
14057                         if (( tot_len != $EXPECTED_LEN )); then
14058                                 cleanup_130
14059                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14060                         else
14061                                 (( num_luns += 1 ))
14062                                 tot_len=0
14063                         fi
14064                 fi
14065                 (( tot_len += ext_len ))
14066                 last_lun=$frag_lun
14067         done
14068         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14069                 cleanup_130
14070                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14071         fi
14072
14073         echo "FIEMAP with continuation calls succeeded"
14074 }
14075 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14076
14077 test_130f() {
14078         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14079         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14080
14081         local fm_file=$DIR/$tfile
14082         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14083                 error "multiop create with lov_delay_create on $fm_file"
14084
14085         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14086         filefrag_extents=$(filefrag -vek $fm_file |
14087                            awk '/extents? found/ { print $2 }')
14088         if [[ "$filefrag_extents" != "0" ]]; then
14089                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14090         fi
14091
14092         rm -f $fm_file
14093 }
14094 run_test 130f "FIEMAP (unstriped file)"
14095
14096 test_130g() {
14097         local file=$DIR/$tfile
14098         local nr=$((OSTCOUNT * 100))
14099
14100         $LFS setstripe -C $nr $file ||
14101                 error "failed to setstripe -C $nr $file"
14102
14103         dd if=/dev/zero of=$file count=$nr bs=1M
14104         sync
14105         nr=$($LFS getstripe -c $file)
14106
14107         local extents=$(filefrag -v $file |
14108                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14109
14110         echo "filefrag list $extents extents in file with stripecount $nr"
14111         if (( extents < nr )); then
14112                 $LFS getstripe $file
14113                 filefrag -v $file
14114                 error "filefrag printed $extents < $nr extents"
14115         fi
14116
14117         rm -f $file
14118 }
14119 run_test 130g "FIEMAP (overstripe file)"
14120
14121 # Test for writev/readv
14122 test_131a() {
14123         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14124                 error "writev test failed"
14125         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14126                 error "readv failed"
14127         rm -f $DIR/$tfile
14128 }
14129 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14130
14131 test_131b() {
14132         local fsize=$((524288 + 1048576 + 1572864))
14133         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14134                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14135                         error "append writev test failed"
14136
14137         ((fsize += 1572864 + 1048576))
14138         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14139                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14140                         error "append writev test failed"
14141         rm -f $DIR/$tfile
14142 }
14143 run_test 131b "test append writev"
14144
14145 test_131c() {
14146         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14147         error "NOT PASS"
14148 }
14149 run_test 131c "test read/write on file w/o objects"
14150
14151 test_131d() {
14152         rwv -f $DIR/$tfile -w -n 1 1572864
14153         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14154         if [ "$NOB" != 1572864 ]; then
14155                 error "Short read filed: read $NOB bytes instead of 1572864"
14156         fi
14157         rm -f $DIR/$tfile
14158 }
14159 run_test 131d "test short read"
14160
14161 test_131e() {
14162         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14163         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14164         error "read hitting hole failed"
14165         rm -f $DIR/$tfile
14166 }
14167 run_test 131e "test read hitting hole"
14168
14169 check_stats() {
14170         local facet=$1
14171         local op=$2
14172         local want=${3:-0}
14173         local res
14174
14175         case $facet in
14176         mds*) res=$(do_facet $facet \
14177                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14178                  ;;
14179         ost*) res=$(do_facet $facet \
14180                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14181                  ;;
14182         *) error "Wrong facet '$facet'" ;;
14183         esac
14184         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14185         # if the argument $3 is zero, it means any stat increment is ok.
14186         if [[ $want -gt 0 ]]; then
14187                 local count=$(echo $res | awk '{ print $2 }')
14188                 [[ $count -ne $want ]] &&
14189                         error "The $op counter on $facet is $count, not $want"
14190         fi
14191 }
14192
14193 test_133a() {
14194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14195         remote_ost_nodsh && skip "remote OST with nodsh"
14196         remote_mds_nodsh && skip "remote MDS with nodsh"
14197         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14198                 skip_env "MDS doesn't support rename stats"
14199
14200         local testdir=$DIR/${tdir}/stats_testdir
14201
14202         mkdir -p $DIR/${tdir}
14203
14204         # clear stats.
14205         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14206         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14207
14208         # verify mdt stats first.
14209         mkdir ${testdir} || error "mkdir failed"
14210         check_stats $SINGLEMDS "mkdir" 1
14211         touch ${testdir}/${tfile} || error "touch failed"
14212         check_stats $SINGLEMDS "open" 1
14213         check_stats $SINGLEMDS "close" 1
14214         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14215                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14216                 check_stats $SINGLEMDS "mknod" 2
14217         }
14218         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14219         check_stats $SINGLEMDS "unlink" 1
14220         rm -f ${testdir}/${tfile} || error "file remove failed"
14221         check_stats $SINGLEMDS "unlink" 2
14222
14223         # remove working dir and check mdt stats again.
14224         rmdir ${testdir} || error "rmdir failed"
14225         check_stats $SINGLEMDS "rmdir" 1
14226
14227         local testdir1=$DIR/${tdir}/stats_testdir1
14228         mkdir -p ${testdir}
14229         mkdir -p ${testdir1}
14230         touch ${testdir1}/test1
14231         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14232         check_stats $SINGLEMDS "crossdir_rename" 1
14233
14234         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14235         check_stats $SINGLEMDS "samedir_rename" 1
14236
14237         rm -rf $DIR/${tdir}
14238 }
14239 run_test 133a "Verifying MDT stats ========================================"
14240
14241 test_133b() {
14242         local res
14243
14244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14245         remote_ost_nodsh && skip "remote OST with nodsh"
14246         remote_mds_nodsh && skip "remote MDS with nodsh"
14247
14248         local testdir=$DIR/${tdir}/stats_testdir
14249
14250         mkdir -p ${testdir} || error "mkdir failed"
14251         touch ${testdir}/${tfile} || error "touch failed"
14252         cancel_lru_locks mdc
14253
14254         # clear stats.
14255         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14256         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14257
14258         # extra mdt stats verification.
14259         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14260         check_stats $SINGLEMDS "setattr" 1
14261         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14262         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14263         then            # LU-1740
14264                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14265                 check_stats $SINGLEMDS "getattr" 1
14266         fi
14267         rm -rf $DIR/${tdir}
14268
14269         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14270         # so the check below is not reliable
14271         [ $MDSCOUNT -eq 1 ] || return 0
14272
14273         # Sleep to avoid a cached response.
14274         #define OBD_STATFS_CACHE_SECONDS 1
14275         sleep 2
14276         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14277         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14278         $LFS df || error "lfs failed"
14279         check_stats $SINGLEMDS "statfs" 1
14280
14281         # check aggregated statfs (LU-10018)
14282         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14283                 return 0
14284         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14285                 return 0
14286         sleep 2
14287         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14288         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14289         df $DIR
14290         check_stats $SINGLEMDS "statfs" 1
14291
14292         # We want to check that the client didn't send OST_STATFS to
14293         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14294         # extra care is needed here.
14295         if remote_mds; then
14296                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14297                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14298
14299                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14300                 [ "$res" ] && error "OST got STATFS"
14301         fi
14302
14303         return 0
14304 }
14305 run_test 133b "Verifying extra MDT stats =================================="
14306
14307 test_133c() {
14308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14309         remote_ost_nodsh && skip "remote OST with nodsh"
14310         remote_mds_nodsh && skip "remote MDS with nodsh"
14311
14312         local testdir=$DIR/$tdir/stats_testdir
14313
14314         test_mkdir -p $testdir
14315
14316         # verify obdfilter stats.
14317         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14318         sync
14319         cancel_lru_locks osc
14320         wait_delete_completed
14321
14322         # clear stats.
14323         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14324         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14325
14326         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14327                 error "dd failed"
14328         sync
14329         cancel_lru_locks osc
14330         check_stats ost1 "write" 1
14331
14332         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14333         check_stats ost1 "read" 1
14334
14335         > $testdir/$tfile || error "truncate failed"
14336         check_stats ost1 "punch" 1
14337
14338         rm -f $testdir/$tfile || error "file remove failed"
14339         wait_delete_completed
14340         check_stats ost1 "destroy" 1
14341
14342         rm -rf $DIR/$tdir
14343 }
14344 run_test 133c "Verifying OST stats ========================================"
14345
14346 order_2() {
14347         local value=$1
14348         local orig=$value
14349         local order=1
14350
14351         while [ $value -ge 2 ]; do
14352                 order=$((order*2))
14353                 value=$((value/2))
14354         done
14355
14356         if [ $orig -gt $order ]; then
14357                 order=$((order*2))
14358         fi
14359         echo $order
14360 }
14361
14362 size_in_KMGT() {
14363     local value=$1
14364     local size=('K' 'M' 'G' 'T');
14365     local i=0
14366     local size_string=$value
14367
14368     while [ $value -ge 1024 ]; do
14369         if [ $i -gt 3 ]; then
14370             #T is the biggest unit we get here, if that is bigger,
14371             #just return XXXT
14372             size_string=${value}T
14373             break
14374         fi
14375         value=$((value >> 10))
14376         if [ $value -lt 1024 ]; then
14377             size_string=${value}${size[$i]}
14378             break
14379         fi
14380         i=$((i + 1))
14381     done
14382
14383     echo $size_string
14384 }
14385
14386 get_rename_size() {
14387         local size=$1
14388         local context=${2:-.}
14389         local sample=$(do_facet $SINGLEMDS $LCTL \
14390                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14391                 grep -A1 $context |
14392                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14393         echo $sample
14394 }
14395
14396 test_133d() {
14397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14398         remote_ost_nodsh && skip "remote OST with nodsh"
14399         remote_mds_nodsh && skip "remote MDS with nodsh"
14400         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14401                 skip_env "MDS doesn't support rename stats"
14402
14403         local testdir1=$DIR/${tdir}/stats_testdir1
14404         local testdir2=$DIR/${tdir}/stats_testdir2
14405         mkdir -p $DIR/${tdir}
14406
14407         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14408
14409         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14410         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14411
14412         createmany -o $testdir1/test 512 || error "createmany failed"
14413
14414         # check samedir rename size
14415         mv ${testdir1}/test0 ${testdir1}/test_0
14416
14417         local testdir1_size=$(ls -l $DIR/${tdir} |
14418                 awk '/stats_testdir1/ {print $5}')
14419         local testdir2_size=$(ls -l $DIR/${tdir} |
14420                 awk '/stats_testdir2/ {print $5}')
14421
14422         testdir1_size=$(order_2 $testdir1_size)
14423         testdir2_size=$(order_2 $testdir2_size)
14424
14425         testdir1_size=$(size_in_KMGT $testdir1_size)
14426         testdir2_size=$(size_in_KMGT $testdir2_size)
14427
14428         echo "source rename dir size: ${testdir1_size}"
14429         echo "target rename dir size: ${testdir2_size}"
14430
14431         local cmd="do_facet $SINGLEMDS $LCTL "
14432         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14433
14434         eval $cmd || error "$cmd failed"
14435         local samedir=$($cmd | grep 'same_dir')
14436         local same_sample=$(get_rename_size $testdir1_size)
14437         [ -z "$samedir" ] && error "samedir_rename_size count error"
14438         [[ $same_sample -eq 1 ]] ||
14439                 error "samedir_rename_size error $same_sample"
14440         echo "Check same dir rename stats success"
14441
14442         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14443
14444         # check crossdir rename size
14445         mv ${testdir1}/test_0 ${testdir2}/test_0
14446
14447         testdir1_size=$(ls -l $DIR/${tdir} |
14448                 awk '/stats_testdir1/ {print $5}')
14449         testdir2_size=$(ls -l $DIR/${tdir} |
14450                 awk '/stats_testdir2/ {print $5}')
14451
14452         testdir1_size=$(order_2 $testdir1_size)
14453         testdir2_size=$(order_2 $testdir2_size)
14454
14455         testdir1_size=$(size_in_KMGT $testdir1_size)
14456         testdir2_size=$(size_in_KMGT $testdir2_size)
14457
14458         echo "source rename dir size: ${testdir1_size}"
14459         echo "target rename dir size: ${testdir2_size}"
14460
14461         eval $cmd || error "$cmd failed"
14462         local crossdir=$($cmd | grep 'crossdir')
14463         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14464         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14465         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14466         [[ $src_sample -eq 1 ]] ||
14467                 error "crossdir_rename_size error $src_sample"
14468         [[ $tgt_sample -eq 1 ]] ||
14469                 error "crossdir_rename_size error $tgt_sample"
14470         echo "Check cross dir rename stats success"
14471         rm -rf $DIR/${tdir}
14472 }
14473 run_test 133d "Verifying rename_stats ========================================"
14474
14475 test_133e() {
14476         remote_mds_nodsh && skip "remote MDS with nodsh"
14477         remote_ost_nodsh && skip "remote OST with nodsh"
14478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14479
14480         local testdir=$DIR/${tdir}/stats_testdir
14481         local ctr f0 f1 bs=32768 count=42 sum
14482
14483         mkdir -p ${testdir} || error "mkdir failed"
14484
14485         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14486
14487         for ctr in {write,read}_bytes; do
14488                 sync
14489                 cancel_lru_locks osc
14490
14491                 do_facet ost1 $LCTL set_param -n \
14492                         "obdfilter.*.exports.clear=clear"
14493
14494                 if [ $ctr = write_bytes ]; then
14495                         f0=/dev/zero
14496                         f1=${testdir}/${tfile}
14497                 else
14498                         f0=${testdir}/${tfile}
14499                         f1=/dev/null
14500                 fi
14501
14502                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14503                         error "dd failed"
14504                 sync
14505                 cancel_lru_locks osc
14506
14507                 sum=$(do_facet ost1 $LCTL get_param \
14508                         "obdfilter.*.exports.*.stats" |
14509                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14510                                 $1 == ctr { sum += $7 }
14511                                 END { printf("%0.0f", sum) }')
14512
14513                 if ((sum != bs * count)); then
14514                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14515                 fi
14516         done
14517
14518         rm -rf $DIR/${tdir}
14519 }
14520 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14521
14522 test_133f() {
14523         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14524                 skip "too old lustre for get_param -R ($facet_ver)"
14525
14526         # verifying readability.
14527         $LCTL get_param -R '*' &> /dev/null
14528
14529         # Verifing writability with badarea_io.
14530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14531         local skipped_params='force_lbug|changelog_mask|daemon_file'
14532         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14533                 egrep -v "$skipped_params" |
14534                 xargs -n 1 find $proc_dirs -name |
14535                 xargs -n 1 badarea_io ||
14536                 error "client badarea_io failed"
14537
14538         # remount the FS in case writes/reads /proc break the FS
14539         cleanup || error "failed to unmount"
14540         setup || error "failed to setup"
14541 }
14542 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14543
14544 test_133g() {
14545         remote_mds_nodsh && skip "remote MDS with nodsh"
14546         remote_ost_nodsh && skip "remote OST with nodsh"
14547
14548         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14549         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14550         local facet
14551         for facet in mds1 ost1; do
14552                 local facet_ver=$(lustre_version_code $facet)
14553                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14554                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14555                 else
14556                         log "$facet: too old lustre for get_param -R"
14557                 fi
14558                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14559                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14560                                 tr -d = | egrep -v $skipped_params |
14561                                 xargs -n 1 find $proc_dirs -name |
14562                                 xargs -n 1 badarea_io" ||
14563                                         error "$facet badarea_io failed"
14564                 else
14565                         skip_noexit "$facet: too old lustre for get_param -R"
14566                 fi
14567         done
14568
14569         # remount the FS in case writes/reads /proc break the FS
14570         cleanup || error "failed to unmount"
14571         setup || error "failed to setup"
14572 }
14573 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14574
14575 test_133h() {
14576         remote_mds_nodsh && skip "remote MDS with nodsh"
14577         remote_ost_nodsh && skip "remote OST with nodsh"
14578         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14579                 skip "Need MDS version at least 2.9.54"
14580
14581         local facet
14582         for facet in client mds1 ost1; do
14583                 # Get the list of files that are missing the terminating newline
14584                 local plist=$(do_facet $facet
14585                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14586                 local ent
14587                 for ent in $plist; do
14588                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14589                                 awk -v FS='\v' -v RS='\v\v' \
14590                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14591                                         print FILENAME}'" 2>/dev/null)
14592                         [ -z $missing ] || {
14593                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14594                                 error "file does not end with newline: $facet-$ent"
14595                         }
14596                 done
14597         done
14598 }
14599 run_test 133h "Proc files should end with newlines"
14600
14601 test_134a() {
14602         remote_mds_nodsh && skip "remote MDS with nodsh"
14603         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14604                 skip "Need MDS version at least 2.7.54"
14605
14606         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14607         cancel_lru_locks mdc
14608
14609         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14610         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14611         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14612
14613         local nr=1000
14614         createmany -o $DIR/$tdir/f $nr ||
14615                 error "failed to create $nr files in $DIR/$tdir"
14616         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14617
14618         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14619         do_facet mds1 $LCTL set_param fail_loc=0x327
14620         do_facet mds1 $LCTL set_param fail_val=500
14621         touch $DIR/$tdir/m
14622
14623         echo "sleep 10 seconds ..."
14624         sleep 10
14625         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14626
14627         do_facet mds1 $LCTL set_param fail_loc=0
14628         do_facet mds1 $LCTL set_param fail_val=0
14629         [ $lck_cnt -lt $unused ] ||
14630                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14631
14632         rm $DIR/$tdir/m
14633         unlinkmany $DIR/$tdir/f $nr
14634 }
14635 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14636
14637 test_134b() {
14638         remote_mds_nodsh && skip "remote MDS with nodsh"
14639         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14640                 skip "Need MDS version at least 2.7.54"
14641
14642         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14643         cancel_lru_locks mdc
14644
14645         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14646                         ldlm.lock_reclaim_threshold_mb)
14647         # disable reclaim temporarily
14648         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14649
14650         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14651         do_facet mds1 $LCTL set_param fail_loc=0x328
14652         do_facet mds1 $LCTL set_param fail_val=500
14653
14654         $LCTL set_param debug=+trace
14655
14656         local nr=600
14657         createmany -o $DIR/$tdir/f $nr &
14658         local create_pid=$!
14659
14660         echo "Sleep $TIMEOUT seconds ..."
14661         sleep $TIMEOUT
14662         if ! ps -p $create_pid  > /dev/null 2>&1; then
14663                 do_facet mds1 $LCTL set_param fail_loc=0
14664                 do_facet mds1 $LCTL set_param fail_val=0
14665                 do_facet mds1 $LCTL set_param \
14666                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14667                 error "createmany finished incorrectly!"
14668         fi
14669         do_facet mds1 $LCTL set_param fail_loc=0
14670         do_facet mds1 $LCTL set_param fail_val=0
14671         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14672         wait $create_pid || return 1
14673
14674         unlinkmany $DIR/$tdir/f $nr
14675 }
14676 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14677
14678 test_135() {
14679         remote_mds_nodsh && skip "remote MDS with nodsh"
14680         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14681                 skip "Need MDS version at least 2.13.50"
14682         local fname
14683
14684         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14685
14686 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14687         #set only one record at plain llog
14688         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14689
14690         #fill already existed plain llog each 64767
14691         #wrapping whole catalog
14692         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14693
14694         createmany -o $DIR/$tdir/$tfile_ 64700
14695         for (( i = 0; i < 64700; i = i + 2 ))
14696         do
14697                 rm $DIR/$tdir/$tfile_$i &
14698                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14699                 local pid=$!
14700                 wait $pid
14701         done
14702
14703         #waiting osp synchronization
14704         wait_delete_completed
14705 }
14706 run_test 135 "Race catalog processing"
14707
14708 test_136() {
14709         remote_mds_nodsh && skip "remote MDS with nodsh"
14710         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14711                 skip "Need MDS version at least 2.13.50"
14712         local fname
14713
14714         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14715         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14716         #set only one record at plain llog
14717 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14718         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14719
14720         #fill already existed 2 plain llogs each 64767
14721         #wrapping whole catalog
14722         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14723         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14724         wait_delete_completed
14725
14726         createmany -o $DIR/$tdir/$tfile_ 10
14727         sleep 25
14728
14729         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14730         for (( i = 0; i < 10; i = i + 3 ))
14731         do
14732                 rm $DIR/$tdir/$tfile_$i &
14733                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14734                 local pid=$!
14735                 wait $pid
14736                 sleep 7
14737                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14738         done
14739
14740         #waiting osp synchronization
14741         wait_delete_completed
14742 }
14743 run_test 136 "Race catalog processing 2"
14744
14745 test_140() { #bug-17379
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747
14748         test_mkdir $DIR/$tdir
14749         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14750         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14751
14752         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14753         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14754         local i=0
14755         while i=$((i + 1)); do
14756                 test_mkdir $i
14757                 cd $i || error "Changing to $i"
14758                 ln -s ../stat stat || error "Creating stat symlink"
14759                 # Read the symlink until ELOOP present,
14760                 # not LBUGing the system is considered success,
14761                 # we didn't overrun the stack.
14762                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14763                 if [ $ret -ne 0 ]; then
14764                         if [ $ret -eq 40 ]; then
14765                                 break  # -ELOOP
14766                         else
14767                                 error "Open stat symlink"
14768                                         return
14769                         fi
14770                 fi
14771         done
14772         i=$((i - 1))
14773         echo "The symlink depth = $i"
14774         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14775                 error "Invalid symlink depth"
14776
14777         # Test recursive symlink
14778         ln -s symlink_self symlink_self
14779         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14780         echo "open symlink_self returns $ret"
14781         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14782 }
14783 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14784
14785 test_150a() {
14786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14787
14788         local TF="$TMP/$tfile"
14789
14790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14791         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14792         cp $TF $DIR/$tfile
14793         cancel_lru_locks $OSC
14794         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14795         remount_client $MOUNT
14796         df -P $MOUNT
14797         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14798
14799         $TRUNCATE $TF 6000
14800         $TRUNCATE $DIR/$tfile 6000
14801         cancel_lru_locks $OSC
14802         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14803
14804         echo "12345" >>$TF
14805         echo "12345" >>$DIR/$tfile
14806         cancel_lru_locks $OSC
14807         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14808
14809         echo "12345" >>$TF
14810         echo "12345" >>$DIR/$tfile
14811         cancel_lru_locks $OSC
14812         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14813 }
14814 run_test 150a "truncate/append tests"
14815
14816 test_150b() {
14817         check_set_fallocate_or_skip
14818
14819         touch $DIR/$tfile
14820         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14821         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14822 }
14823 run_test 150b "Verify fallocate (prealloc) functionality"
14824
14825 test_150bb() {
14826         check_set_fallocate_or_skip
14827
14828         touch $DIR/$tfile
14829         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14830         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14831         > $DIR/$tfile
14832         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14833         # precomputed md5sum for 20MB of zeroes
14834         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14835         local sum=($(md5sum $DIR/$tfile))
14836
14837         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14838
14839         check_set_fallocate 1
14840
14841         > $DIR/$tfile
14842         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14843         sum=($(md5sum $DIR/$tfile))
14844
14845         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14846 }
14847 run_test 150bb "Verify fallocate modes both zero space"
14848
14849 test_150c() {
14850         check_set_fallocate_or_skip
14851         local striping="-c2"
14852
14853         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14854         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14855         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14856         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14857         local want=$((OSTCOUNT * 1048576))
14858
14859         # Must allocate all requested space, not more than 5% extra
14860         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14861                 error "bytes $bytes is not $want"
14862
14863         rm -f $DIR/$tfile
14864
14865         echo "verify fallocate on PFL file"
14866
14867         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14868
14869         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14870                 error "Create $DIR/$tfile failed"
14871         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14872         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14873         want=$((512 * 1048576))
14874
14875         # Must allocate all requested space, not more than 5% extra
14876         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14877                 error "bytes $bytes is not $want"
14878 }
14879 run_test 150c "Verify fallocate Size and Blocks"
14880
14881 test_150d() {
14882         check_set_fallocate_or_skip
14883         local striping="-c2"
14884
14885         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14886
14887         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14888         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14889                 error "setstripe failed"
14890         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14891         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14892         local want=$((OSTCOUNT * 1048576))
14893
14894         # Must allocate all requested space, not more than 5% extra
14895         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14896                 error "bytes $bytes is not $want"
14897 }
14898 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14899
14900 test_150e() {
14901         check_set_fallocate_or_skip
14902
14903         echo "df before:"
14904         $LFS df
14905         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14906         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14907                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14908
14909         # Find OST with Minimum Size
14910         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14911                        sort -un | head -1)
14912
14913         # Get 100MB per OST of the available space to reduce run time
14914         # else 60% of the available space if we are running SLOW tests
14915         if [ $SLOW == "no" ]; then
14916                 local space=$((1024 * 100 * OSTCOUNT))
14917         else
14918                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14919         fi
14920
14921         fallocate -l${space}k $DIR/$tfile ||
14922                 error "fallocate ${space}k $DIR/$tfile failed"
14923         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14924
14925         # get size immediately after fallocate. This should be correctly
14926         # updated
14927         local size=$(stat -c '%s' $DIR/$tfile)
14928         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14929
14930         # Sleep for a while for statfs to get updated. And not pull from cache.
14931         sleep 2
14932
14933         echo "df after fallocate:"
14934         $LFS df
14935
14936         (( size / 1024 == space )) || error "size $size != requested $space"
14937         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14938                 error "used $used < space $space"
14939
14940         rm $DIR/$tfile || error "rm failed"
14941         sync
14942         wait_delete_completed
14943
14944         echo "df after unlink:"
14945         $LFS df
14946 }
14947 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14948
14949 test_150f() {
14950         local size
14951         local blocks
14952         local want_size_before=20480 # in bytes
14953         local want_blocks_before=40 # 512 sized blocks
14954         local want_blocks_after=24  # 512 sized blocks
14955         local length=$(((want_blocks_before - want_blocks_after) * 512))
14956
14957         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14958                 skip "need at least 2.14.0 for fallocate punch"
14959
14960         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14961                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14962         fi
14963
14964         check_set_fallocate_or_skip
14965         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14966
14967         [[ "x$DOM" == "xyes" ]] &&
14968                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14969
14970         echo "Verify fallocate punch: Range within the file range"
14971         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14972                 error "dd failed for bs 4096 and count 5"
14973
14974         # Call fallocate with punch range which is within the file range
14975         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14976                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14977         # client must see changes immediately after fallocate
14978         size=$(stat -c '%s' $DIR/$tfile)
14979         blocks=$(stat -c '%b' $DIR/$tfile)
14980
14981         # Verify punch worked.
14982         (( blocks == want_blocks_after )) ||
14983                 error "punch failed: blocks $blocks != $want_blocks_after"
14984
14985         (( size == want_size_before )) ||
14986                 error "punch failed: size $size != $want_size_before"
14987
14988         # Verify there is hole in file
14989         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14990         # precomputed md5sum
14991         local expect="4a9a834a2db02452929c0a348273b4aa"
14992
14993         cksum=($(md5sum $DIR/$tfile))
14994         [[ "${cksum[0]}" == "$expect" ]] ||
14995                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14996
14997         # Start second sub-case for fallocate punch.
14998         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14999         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15000                 error "dd failed for bs 4096 and count 5"
15001
15002         # Punch range less than block size will have no change in block count
15003         want_blocks_after=40  # 512 sized blocks
15004
15005         # Punch overlaps two blocks and less than blocksize
15006         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15007                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15008         size=$(stat -c '%s' $DIR/$tfile)
15009         blocks=$(stat -c '%b' $DIR/$tfile)
15010
15011         # Verify punch worked.
15012         (( blocks == want_blocks_after )) ||
15013                 error "punch failed: blocks $blocks != $want_blocks_after"
15014
15015         (( size == want_size_before )) ||
15016                 error "punch failed: size $size != $want_size_before"
15017
15018         # Verify if range is really zero'ed out. We expect Zeros.
15019         # precomputed md5sum
15020         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15021         cksum=($(md5sum $DIR/$tfile))
15022         [[ "${cksum[0]}" == "$expect" ]] ||
15023                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15024 }
15025 run_test 150f "Verify fallocate punch functionality"
15026
15027 test_150g() {
15028         local space
15029         local size
15030         local blocks
15031         local blocks_after
15032         local size_after
15033         local BS=4096 # Block size in bytes
15034
15035         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15036                 skip "need at least 2.14.0 for fallocate punch"
15037
15038         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15039                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15040         fi
15041
15042         check_set_fallocate_or_skip
15043         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15044
15045         if [[ "x$DOM" == "xyes" ]]; then
15046                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15047                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15048         else
15049                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15050                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15051         fi
15052
15053         # Get 100MB per OST of the available space to reduce run time
15054         # else 60% of the available space if we are running SLOW tests
15055         if [ $SLOW == "no" ]; then
15056                 space=$((1024 * 100 * OSTCOUNT))
15057         else
15058                 # Find OST with Minimum Size
15059                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15060                         sort -un | head -1)
15061                 echo "min size OST: $space"
15062                 space=$(((space * 60)/100 * OSTCOUNT))
15063         fi
15064         # space in 1k units, round to 4k blocks
15065         local blkcount=$((space * 1024 / $BS))
15066
15067         echo "Verify fallocate punch: Very large Range"
15068         fallocate -l${space}k $DIR/$tfile ||
15069                 error "fallocate ${space}k $DIR/$tfile failed"
15070         # write 1M at the end, start and in the middle
15071         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15072                 error "dd failed: bs $BS count 256"
15073         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15074                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15075         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15076                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15077
15078         # Gather stats.
15079         size=$(stat -c '%s' $DIR/$tfile)
15080
15081         # gather punch length.
15082         local punch_size=$((size - (BS * 2)))
15083
15084         echo "punch_size = $punch_size"
15085         echo "size - punch_size: $((size - punch_size))"
15086         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15087
15088         # Call fallocate to punch all except 2 blocks. We leave the
15089         # first and the last block
15090         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15091         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15092                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15093
15094         size_after=$(stat -c '%s' $DIR/$tfile)
15095         blocks_after=$(stat -c '%b' $DIR/$tfile)
15096
15097         # Verify punch worked.
15098         # Size should be kept
15099         (( size == size_after )) ||
15100                 error "punch failed: size $size != $size_after"
15101
15102         # two 4k data blocks to remain plus possible 1 extra extent block
15103         (( blocks_after <= ((BS / 512) * 3) )) ||
15104                 error "too many blocks remains: $blocks_after"
15105
15106         # Verify that file has hole between the first and the last blocks
15107         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15108         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15109
15110         echo "Hole at [$hole_start, $hole_end)"
15111         (( hole_start == BS )) ||
15112                 error "no hole at offset $BS after punch"
15113
15114         (( hole_end == BS + punch_size )) ||
15115                 error "data at offset $hole_end < $((BS + punch_size))"
15116 }
15117 run_test 150g "Verify fallocate punch on large range"
15118
15119 #LU-2902 roc_hit was not able to read all values from lproc
15120 function roc_hit_init() {
15121         local list=$(comma_list $(osts_nodes))
15122         local dir=$DIR/$tdir-check
15123         local file=$dir/$tfile
15124         local BEFORE
15125         local AFTER
15126         local idx
15127
15128         test_mkdir $dir
15129         #use setstripe to do a write to every ost
15130         for i in $(seq 0 $((OSTCOUNT-1))); do
15131                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15132                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15133                 idx=$(printf %04x $i)
15134                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15135                         awk '$1 == "cache_access" {sum += $7}
15136                                 END { printf("%0.0f", sum) }')
15137
15138                 cancel_lru_locks osc
15139                 cat $file >/dev/null
15140
15141                 AFTER=$(get_osd_param $list *OST*$idx stats |
15142                         awk '$1 == "cache_access" {sum += $7}
15143                                 END { printf("%0.0f", sum) }')
15144
15145                 echo BEFORE:$BEFORE AFTER:$AFTER
15146                 if ! let "AFTER - BEFORE == 4"; then
15147                         rm -rf $dir
15148                         error "roc_hit is not safe to use"
15149                 fi
15150                 rm $file
15151         done
15152
15153         rm -rf $dir
15154 }
15155
15156 function roc_hit() {
15157         local list=$(comma_list $(osts_nodes))
15158         echo $(get_osd_param $list '' stats |
15159                 awk '$1 == "cache_hit" {sum += $7}
15160                         END { printf("%0.0f", sum) }')
15161 }
15162
15163 function set_cache() {
15164         local on=1
15165
15166         if [ "$2" == "off" ]; then
15167                 on=0;
15168         fi
15169         local list=$(comma_list $(osts_nodes))
15170         set_osd_param $list '' $1_cache_enable $on
15171
15172         cancel_lru_locks osc
15173 }
15174
15175 test_151() {
15176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15177         remote_ost_nodsh && skip "remote OST with nodsh"
15178
15179         local CPAGES=3
15180         local list=$(comma_list $(osts_nodes))
15181
15182         # check whether obdfilter is cache capable at all
15183         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15184                 skip "not cache-capable obdfilter"
15185         fi
15186
15187         # check cache is enabled on all obdfilters
15188         if get_osd_param $list '' read_cache_enable | grep 0; then
15189                 skip "oss cache is disabled"
15190         fi
15191
15192         set_osd_param $list '' writethrough_cache_enable 1
15193
15194         # check write cache is enabled on all obdfilters
15195         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15196                 skip "oss write cache is NOT enabled"
15197         fi
15198
15199         roc_hit_init
15200
15201         #define OBD_FAIL_OBD_NO_LRU  0x609
15202         do_nodes $list $LCTL set_param fail_loc=0x609
15203
15204         # pages should be in the case right after write
15205         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15206                 error "dd failed"
15207
15208         local BEFORE=$(roc_hit)
15209         cancel_lru_locks osc
15210         cat $DIR/$tfile >/dev/null
15211         local AFTER=$(roc_hit)
15212
15213         do_nodes $list $LCTL set_param fail_loc=0
15214
15215         if ! let "AFTER - BEFORE == CPAGES"; then
15216                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15217         fi
15218
15219         cancel_lru_locks osc
15220         # invalidates OST cache
15221         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15222         set_osd_param $list '' read_cache_enable 0
15223         cat $DIR/$tfile >/dev/null
15224
15225         # now data shouldn't be found in the cache
15226         BEFORE=$(roc_hit)
15227         cancel_lru_locks osc
15228         cat $DIR/$tfile >/dev/null
15229         AFTER=$(roc_hit)
15230         if let "AFTER - BEFORE != 0"; then
15231                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15232         fi
15233
15234         set_osd_param $list '' read_cache_enable 1
15235         rm -f $DIR/$tfile
15236 }
15237 run_test 151 "test cache on oss and controls ==============================="
15238
15239 test_152() {
15240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15241
15242         local TF="$TMP/$tfile"
15243
15244         # simulate ENOMEM during write
15245 #define OBD_FAIL_OST_NOMEM      0x226
15246         lctl set_param fail_loc=0x80000226
15247         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15248         cp $TF $DIR/$tfile
15249         sync || error "sync failed"
15250         lctl set_param fail_loc=0
15251
15252         # discard client's cache
15253         cancel_lru_locks osc
15254
15255         # simulate ENOMEM during read
15256         lctl set_param fail_loc=0x80000226
15257         cmp $TF $DIR/$tfile || error "cmp failed"
15258         lctl set_param fail_loc=0
15259
15260         rm -f $TF
15261 }
15262 run_test 152 "test read/write with enomem ============================"
15263
15264 test_153() {
15265         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15266 }
15267 run_test 153 "test if fdatasync does not crash ======================="
15268
15269 dot_lustre_fid_permission_check() {
15270         local fid=$1
15271         local ffid=$MOUNT/.lustre/fid/$fid
15272         local test_dir=$2
15273
15274         echo "stat fid $fid"
15275         stat $ffid > /dev/null || error "stat $ffid failed."
15276         echo "touch fid $fid"
15277         touch $ffid || error "touch $ffid failed."
15278         echo "write to fid $fid"
15279         cat /etc/hosts > $ffid || error "write $ffid failed."
15280         echo "read fid $fid"
15281         diff /etc/hosts $ffid || error "read $ffid failed."
15282         echo "append write to fid $fid"
15283         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15284         echo "rename fid $fid"
15285         mv $ffid $test_dir/$tfile.1 &&
15286                 error "rename $ffid to $tfile.1 should fail."
15287         touch $test_dir/$tfile.1
15288         mv $test_dir/$tfile.1 $ffid &&
15289                 error "rename $tfile.1 to $ffid should fail."
15290         rm -f $test_dir/$tfile.1
15291         echo "truncate fid $fid"
15292         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15293         echo "link fid $fid"
15294         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15295         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15296                 echo "setfacl fid $fid"
15297                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15298                 echo "getfacl fid $fid"
15299                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15300         fi
15301         echo "unlink fid $fid"
15302         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15303         echo "mknod fid $fid"
15304         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15305
15306         fid=[0xf00000400:0x1:0x0]
15307         ffid=$MOUNT/.lustre/fid/$fid
15308
15309         echo "stat non-exist fid $fid"
15310         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15311         echo "write to non-exist fid $fid"
15312         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15313         echo "link new fid $fid"
15314         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15315
15316         mkdir -p $test_dir/$tdir
15317         touch $test_dir/$tdir/$tfile
15318         fid=$($LFS path2fid $test_dir/$tdir)
15319         rc=$?
15320         [ $rc -ne 0 ] &&
15321                 error "error: could not get fid for $test_dir/$dir/$tfile."
15322
15323         ffid=$MOUNT/.lustre/fid/$fid
15324
15325         echo "ls $fid"
15326         ls $ffid > /dev/null || error "ls $ffid failed."
15327         echo "touch $fid/$tfile.1"
15328         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15329
15330         echo "touch $MOUNT/.lustre/fid/$tfile"
15331         touch $MOUNT/.lustre/fid/$tfile && \
15332                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15333
15334         echo "setxattr to $MOUNT/.lustre/fid"
15335         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15336
15337         echo "listxattr for $MOUNT/.lustre/fid"
15338         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15339
15340         echo "delxattr from $MOUNT/.lustre/fid"
15341         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15342
15343         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15344         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15345                 error "touch invalid fid should fail."
15346
15347         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15348         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15349                 error "touch non-normal fid should fail."
15350
15351         echo "rename $tdir to $MOUNT/.lustre/fid"
15352         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15353                 error "rename to $MOUNT/.lustre/fid should fail."
15354
15355         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15356         then            # LU-3547
15357                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15358                 local new_obf_mode=777
15359
15360                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15361                 chmod $new_obf_mode $DIR/.lustre/fid ||
15362                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15363
15364                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15365                 [ $obf_mode -eq $new_obf_mode ] ||
15366                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15367
15368                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15369                 chmod $old_obf_mode $DIR/.lustre/fid ||
15370                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15371         fi
15372
15373         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15374         fid=$($LFS path2fid $test_dir/$tfile-2)
15375
15376         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15377         then # LU-5424
15378                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15379                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15380                         error "create lov data thru .lustre failed"
15381         fi
15382         echo "cp /etc/passwd $test_dir/$tfile-2"
15383         cp /etc/passwd $test_dir/$tfile-2 ||
15384                 error "copy to $test_dir/$tfile-2 failed."
15385         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15386         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15387                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15388
15389         rm -rf $test_dir/tfile.lnk
15390         rm -rf $test_dir/$tfile-2
15391 }
15392
15393 test_154A() {
15394         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15395                 skip "Need MDS version at least 2.4.1"
15396
15397         local tf=$DIR/$tfile
15398         touch $tf
15399
15400         local fid=$($LFS path2fid $tf)
15401         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15402
15403         # check that we get the same pathname back
15404         local rootpath
15405         local found
15406         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15407                 echo "$rootpath $fid"
15408                 found=$($LFS fid2path $rootpath "$fid")
15409                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15410                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15411         done
15412
15413         # check wrong root path format
15414         rootpath=$MOUNT"_wrong"
15415         found=$($LFS fid2path $rootpath "$fid")
15416         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15417 }
15418 run_test 154A "lfs path2fid and fid2path basic checks"
15419
15420 test_154B() {
15421         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15422                 skip "Need MDS version at least 2.4.1"
15423
15424         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15425         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15426         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15427         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15428
15429         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15430         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15431
15432         # check that we get the same pathname
15433         echo "PFID: $PFID, name: $name"
15434         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15435         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15436         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15437                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15438
15439         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15440 }
15441 run_test 154B "verify the ll_decode_linkea tool"
15442
15443 test_154a() {
15444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15445         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15446         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15447                 skip "Need MDS version at least 2.2.51"
15448         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15449
15450         cp /etc/hosts $DIR/$tfile
15451
15452         fid=$($LFS path2fid $DIR/$tfile)
15453         rc=$?
15454         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15455
15456         dot_lustre_fid_permission_check "$fid" $DIR ||
15457                 error "dot lustre permission check $fid failed"
15458
15459         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15460
15461         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15462
15463         touch $MOUNT/.lustre/file &&
15464                 error "creation is not allowed under .lustre"
15465
15466         mkdir $MOUNT/.lustre/dir &&
15467                 error "mkdir is not allowed under .lustre"
15468
15469         rm -rf $DIR/$tfile
15470 }
15471 run_test 154a "Open-by-FID"
15472
15473 test_154b() {
15474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15475         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15477         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15478                 skip "Need MDS version at least 2.2.51"
15479
15480         local remote_dir=$DIR/$tdir/remote_dir
15481         local MDTIDX=1
15482         local rc=0
15483
15484         mkdir -p $DIR/$tdir
15485         $LFS mkdir -i $MDTIDX $remote_dir ||
15486                 error "create remote directory failed"
15487
15488         cp /etc/hosts $remote_dir/$tfile
15489
15490         fid=$($LFS path2fid $remote_dir/$tfile)
15491         rc=$?
15492         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15493
15494         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15495                 error "dot lustre permission check $fid failed"
15496         rm -rf $DIR/$tdir
15497 }
15498 run_test 154b "Open-by-FID for remote directory"
15499
15500 test_154c() {
15501         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15502                 skip "Need MDS version at least 2.4.1"
15503
15504         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15505         local FID1=$($LFS path2fid $DIR/$tfile.1)
15506         local FID2=$($LFS path2fid $DIR/$tfile.2)
15507         local FID3=$($LFS path2fid $DIR/$tfile.3)
15508
15509         local N=1
15510         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15511                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15512                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15513                 local want=FID$N
15514                 [ "$FID" = "${!want}" ] ||
15515                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15516                 N=$((N + 1))
15517         done
15518
15519         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15520         do
15521                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15522                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15523                 N=$((N + 1))
15524         done
15525 }
15526 run_test 154c "lfs path2fid and fid2path multiple arguments"
15527
15528 test_154d() {
15529         remote_mds_nodsh && skip "remote MDS with nodsh"
15530         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15531                 skip "Need MDS version at least 2.5.53"
15532
15533         if remote_mds; then
15534                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15535         else
15536                 nid="0@lo"
15537         fi
15538         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15539         local fd
15540         local cmd
15541
15542         rm -f $DIR/$tfile
15543         touch $DIR/$tfile
15544
15545         local fid=$($LFS path2fid $DIR/$tfile)
15546         # Open the file
15547         fd=$(free_fd)
15548         cmd="exec $fd<$DIR/$tfile"
15549         eval $cmd
15550         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15551         echo "$fid_list" | grep "$fid"
15552         rc=$?
15553
15554         cmd="exec $fd>/dev/null"
15555         eval $cmd
15556         if [ $rc -ne 0 ]; then
15557                 error "FID $fid not found in open files list $fid_list"
15558         fi
15559 }
15560 run_test 154d "Verify open file fid"
15561
15562 test_154e()
15563 {
15564         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15565                 skip "Need MDS version at least 2.6.50"
15566
15567         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15568                 error ".lustre returned by readdir"
15569         fi
15570 }
15571 run_test 154e ".lustre is not returned by readdir"
15572
15573 test_154f() {
15574         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15575
15576         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15577         mkdir_on_mdt0 $DIR/$tdir
15578         # test dirs inherit from its stripe
15579         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15580         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15581         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15582         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15583         touch $DIR/f
15584
15585         # get fid of parents
15586         local FID0=$($LFS path2fid $DIR/$tdir)
15587         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15588         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15589         local FID3=$($LFS path2fid $DIR)
15590
15591         # check that path2fid --parents returns expected <parent_fid>/name
15592         # 1) test for a directory (single parent)
15593         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15594         [ "$parent" == "$FID0/foo1" ] ||
15595                 error "expected parent: $FID0/foo1, got: $parent"
15596
15597         # 2) test for a file with nlink > 1 (multiple parents)
15598         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15599         echo "$parent" | grep -F "$FID1/$tfile" ||
15600                 error "$FID1/$tfile not returned in parent list"
15601         echo "$parent" | grep -F "$FID2/link" ||
15602                 error "$FID2/link not returned in parent list"
15603
15604         # 3) get parent by fid
15605         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15606         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15607         echo "$parent" | grep -F "$FID1/$tfile" ||
15608                 error "$FID1/$tfile not returned in parent list (by fid)"
15609         echo "$parent" | grep -F "$FID2/link" ||
15610                 error "$FID2/link not returned in parent list (by fid)"
15611
15612         # 4) test for entry in root directory
15613         parent=$($LFS path2fid --parents $DIR/f)
15614         echo "$parent" | grep -F "$FID3/f" ||
15615                 error "$FID3/f not returned in parent list"
15616
15617         # 5) test it on root directory
15618         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15619                 error "$MOUNT should not have parents"
15620
15621         # enable xattr caching and check that linkea is correctly updated
15622         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15623         save_lustre_params client "llite.*.xattr_cache" > $save
15624         lctl set_param llite.*.xattr_cache 1
15625
15626         # 6.1) linkea update on rename
15627         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15628
15629         # get parents by fid
15630         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15631         # foo1 should no longer be returned in parent list
15632         echo "$parent" | grep -F "$FID1" &&
15633                 error "$FID1 should no longer be in parent list"
15634         # the new path should appear
15635         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15636                 error "$FID2/$tfile.moved is not in parent list"
15637
15638         # 6.2) linkea update on unlink
15639         rm -f $DIR/$tdir/foo2/link
15640         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15641         # foo2/link should no longer be returned in parent list
15642         echo "$parent" | grep -F "$FID2/link" &&
15643                 error "$FID2/link should no longer be in parent list"
15644         true
15645
15646         rm -f $DIR/f
15647         restore_lustre_params < $save
15648         rm -f $save
15649 }
15650 run_test 154f "get parent fids by reading link ea"
15651
15652 test_154g()
15653 {
15654         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15655         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15656            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15657                 skip "Need MDS version at least 2.6.92"
15658
15659         mkdir_on_mdt0 $DIR/$tdir
15660         llapi_fid_test -d $DIR/$tdir
15661 }
15662 run_test 154g "various llapi FID tests"
15663
15664 test_155_small_load() {
15665     local temp=$TMP/$tfile
15666     local file=$DIR/$tfile
15667
15668     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15669         error "dd of=$temp bs=6096 count=1 failed"
15670     cp $temp $file
15671     cancel_lru_locks $OSC
15672     cmp $temp $file || error "$temp $file differ"
15673
15674     $TRUNCATE $temp 6000
15675     $TRUNCATE $file 6000
15676     cmp $temp $file || error "$temp $file differ (truncate1)"
15677
15678     echo "12345" >>$temp
15679     echo "12345" >>$file
15680     cmp $temp $file || error "$temp $file differ (append1)"
15681
15682     echo "12345" >>$temp
15683     echo "12345" >>$file
15684     cmp $temp $file || error "$temp $file differ (append2)"
15685
15686     rm -f $temp $file
15687     true
15688 }
15689
15690 test_155_big_load() {
15691         remote_ost_nodsh && skip "remote OST with nodsh"
15692
15693         local temp=$TMP/$tfile
15694         local file=$DIR/$tfile
15695
15696         free_min_max
15697         local cache_size=$(do_facet ost$((MAXI+1)) \
15698                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15699
15700         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15701         # pre-set value
15702         if [ -z "$cache_size" ]; then
15703                 cache_size=256
15704         fi
15705         local large_file_size=$((cache_size * 2))
15706
15707         echo "OSS cache size: $cache_size KB"
15708         echo "Large file size: $large_file_size KB"
15709
15710         [ $MAXV -le $large_file_size ] &&
15711                 skip_env "max available OST size needs > $large_file_size KB"
15712
15713         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15714
15715         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15716                 error "dd of=$temp bs=$large_file_size count=1k failed"
15717         cp $temp $file
15718         ls -lh $temp $file
15719         cancel_lru_locks osc
15720         cmp $temp $file || error "$temp $file differ"
15721
15722         rm -f $temp $file
15723         true
15724 }
15725
15726 save_writethrough() {
15727         local facets=$(get_facets OST)
15728
15729         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15730 }
15731
15732 test_155a() {
15733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15734
15735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15736
15737         save_writethrough $p
15738
15739         set_cache read on
15740         set_cache writethrough on
15741         test_155_small_load
15742         restore_lustre_params < $p
15743         rm -f $p
15744 }
15745 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15746
15747 test_155b() {
15748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15749
15750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15751
15752         save_writethrough $p
15753
15754         set_cache read on
15755         set_cache writethrough off
15756         test_155_small_load
15757         restore_lustre_params < $p
15758         rm -f $p
15759 }
15760 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15761
15762 test_155c() {
15763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15764
15765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15766
15767         save_writethrough $p
15768
15769         set_cache read off
15770         set_cache writethrough on
15771         test_155_small_load
15772         restore_lustre_params < $p
15773         rm -f $p
15774 }
15775 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15776
15777 test_155d() {
15778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15779
15780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15781
15782         save_writethrough $p
15783
15784         set_cache read off
15785         set_cache writethrough off
15786         test_155_small_load
15787         restore_lustre_params < $p
15788         rm -f $p
15789 }
15790 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15791
15792 test_155e() {
15793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15794
15795         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15796
15797         save_writethrough $p
15798
15799         set_cache read on
15800         set_cache writethrough on
15801         test_155_big_load
15802         restore_lustre_params < $p
15803         rm -f $p
15804 }
15805 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15806
15807 test_155f() {
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809
15810         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15811
15812         save_writethrough $p
15813
15814         set_cache read on
15815         set_cache writethrough off
15816         test_155_big_load
15817         restore_lustre_params < $p
15818         rm -f $p
15819 }
15820 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15821
15822 test_155g() {
15823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15824
15825         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15826
15827         save_writethrough $p
15828
15829         set_cache read off
15830         set_cache writethrough on
15831         test_155_big_load
15832         restore_lustre_params < $p
15833         rm -f $p
15834 }
15835 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15836
15837 test_155h() {
15838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15839
15840         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15841
15842         save_writethrough $p
15843
15844         set_cache read off
15845         set_cache writethrough off
15846         test_155_big_load
15847         restore_lustre_params < $p
15848         rm -f $p
15849 }
15850 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15851
15852 test_156() {
15853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15854         remote_ost_nodsh && skip "remote OST with nodsh"
15855         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15856                 skip "stats not implemented on old servers"
15857         [ "$ost1_FSTYPE" = "zfs" ] &&
15858                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15859
15860         local CPAGES=3
15861         local BEFORE
15862         local AFTER
15863         local file="$DIR/$tfile"
15864         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15865
15866         save_writethrough $p
15867         roc_hit_init
15868
15869         log "Turn on read and write cache"
15870         set_cache read on
15871         set_cache writethrough on
15872
15873         log "Write data and read it back."
15874         log "Read should be satisfied from the cache."
15875         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15876         BEFORE=$(roc_hit)
15877         cancel_lru_locks osc
15878         cat $file >/dev/null
15879         AFTER=$(roc_hit)
15880         if ! let "AFTER - BEFORE == CPAGES"; then
15881                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15882         else
15883                 log "cache hits: before: $BEFORE, after: $AFTER"
15884         fi
15885
15886         log "Read again; it should be satisfied from the cache."
15887         BEFORE=$AFTER
15888         cancel_lru_locks osc
15889         cat $file >/dev/null
15890         AFTER=$(roc_hit)
15891         if ! let "AFTER - BEFORE == CPAGES"; then
15892                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15893         else
15894                 log "cache hits:: before: $BEFORE, after: $AFTER"
15895         fi
15896
15897         log "Turn off the read cache and turn on the write cache"
15898         set_cache read off
15899         set_cache writethrough on
15900
15901         log "Read again; it should be satisfied from the cache."
15902         BEFORE=$(roc_hit)
15903         cancel_lru_locks osc
15904         cat $file >/dev/null
15905         AFTER=$(roc_hit)
15906         if ! let "AFTER - BEFORE == CPAGES"; then
15907                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15908         else
15909                 log "cache hits:: before: $BEFORE, after: $AFTER"
15910         fi
15911
15912         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15913                 # > 2.12.56 uses pagecache if cached
15914                 log "Read again; it should not be satisfied from the cache."
15915                 BEFORE=$AFTER
15916                 cancel_lru_locks osc
15917                 cat $file >/dev/null
15918                 AFTER=$(roc_hit)
15919                 if ! let "AFTER - BEFORE == 0"; then
15920                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15921                 else
15922                         log "cache hits:: before: $BEFORE, after: $AFTER"
15923                 fi
15924         fi
15925
15926         log "Write data and read it back."
15927         log "Read should be satisfied from the cache."
15928         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15929         BEFORE=$(roc_hit)
15930         cancel_lru_locks osc
15931         cat $file >/dev/null
15932         AFTER=$(roc_hit)
15933         if ! let "AFTER - BEFORE == CPAGES"; then
15934                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15935         else
15936                 log "cache hits:: before: $BEFORE, after: $AFTER"
15937         fi
15938
15939         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15940                 # > 2.12.56 uses pagecache if cached
15941                 log "Read again; it should not be satisfied from the cache."
15942                 BEFORE=$AFTER
15943                 cancel_lru_locks osc
15944                 cat $file >/dev/null
15945                 AFTER=$(roc_hit)
15946                 if ! let "AFTER - BEFORE == 0"; then
15947                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15948                 else
15949                         log "cache hits:: before: $BEFORE, after: $AFTER"
15950                 fi
15951         fi
15952
15953         log "Turn off read and write cache"
15954         set_cache read off
15955         set_cache writethrough off
15956
15957         log "Write data and read it back"
15958         log "It should not be satisfied from the cache."
15959         rm -f $file
15960         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15961         cancel_lru_locks osc
15962         BEFORE=$(roc_hit)
15963         cat $file >/dev/null
15964         AFTER=$(roc_hit)
15965         if ! let "AFTER - BEFORE == 0"; then
15966                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15967         else
15968                 log "cache hits:: before: $BEFORE, after: $AFTER"
15969         fi
15970
15971         log "Turn on the read cache and turn off the write cache"
15972         set_cache read on
15973         set_cache writethrough off
15974
15975         log "Write data and read it back"
15976         log "It should not be satisfied from the cache."
15977         rm -f $file
15978         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15979         BEFORE=$(roc_hit)
15980         cancel_lru_locks osc
15981         cat $file >/dev/null
15982         AFTER=$(roc_hit)
15983         if ! let "AFTER - BEFORE == 0"; then
15984                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15985         else
15986                 log "cache hits:: before: $BEFORE, after: $AFTER"
15987         fi
15988
15989         log "Read again; it should be satisfied from the cache."
15990         BEFORE=$(roc_hit)
15991         cancel_lru_locks osc
15992         cat $file >/dev/null
15993         AFTER=$(roc_hit)
15994         if ! let "AFTER - BEFORE == CPAGES"; then
15995                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15996         else
15997                 log "cache hits:: before: $BEFORE, after: $AFTER"
15998         fi
15999
16000         restore_lustre_params < $p
16001         rm -f $p $file
16002 }
16003 run_test 156 "Verification of tunables"
16004
16005 test_160a() {
16006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16007         remote_mds_nodsh && skip "remote MDS with nodsh"
16008         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16009                 skip "Need MDS version at least 2.2.0"
16010
16011         changelog_register || error "changelog_register failed"
16012         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16013         changelog_users $SINGLEMDS | grep -q $cl_user ||
16014                 error "User $cl_user not found in changelog_users"
16015
16016         mkdir_on_mdt0 $DIR/$tdir
16017
16018         # change something
16019         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16020         changelog_clear 0 || error "changelog_clear failed"
16021         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16022         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16023         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16024         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16025         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16026         rm $DIR/$tdir/pics/desktop.jpg
16027
16028         echo "verifying changelog mask"
16029         changelog_chmask "-MKDIR"
16030         changelog_chmask "-CLOSE"
16031
16032         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16033         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16034
16035         changelog_chmask "+MKDIR"
16036         changelog_chmask "+CLOSE"
16037
16038         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16039         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16040
16041         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16042         CLOSES=$(changelog_dump | grep -c "CLOSE")
16043         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16044         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16045
16046         # verify contents
16047         echo "verifying target fid"
16048         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16049         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16050         [ "$fidc" == "$fidf" ] ||
16051                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16052         echo "verifying parent fid"
16053         # The FID returned from the Changelog may be the directory shard on
16054         # a different MDT, and not the FID returned by path2fid on the parent.
16055         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16056         # since this is what will matter when recreating this file in the tree.
16057         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16058         local pathp=$($LFS fid2path $MOUNT "$fidp")
16059         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16060                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16061
16062         echo "getting records for $cl_user"
16063         changelog_users $SINGLEMDS
16064         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16065         local nclr=3
16066         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16067                 error "changelog_clear failed"
16068         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16069         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16070         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16071                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16072
16073         local min0_rec=$(changelog_users $SINGLEMDS |
16074                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16075         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16076                           awk '{ print $1; exit; }')
16077
16078         changelog_dump | tail -n 5
16079         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16080         [ $first_rec == $((min0_rec + 1)) ] ||
16081                 error "first index should be $min0_rec + 1 not $first_rec"
16082
16083         # LU-3446 changelog index reset on MDT restart
16084         local cur_rec1=$(changelog_users $SINGLEMDS |
16085                          awk '/^current.index:/ { print $NF }')
16086         changelog_clear 0 ||
16087                 error "clear all changelog records for $cl_user failed"
16088         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16089         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16090                 error "Fail to start $SINGLEMDS"
16091         local cur_rec2=$(changelog_users $SINGLEMDS |
16092                          awk '/^current.index:/ { print $NF }')
16093         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16094         [ $cur_rec1 == $cur_rec2 ] ||
16095                 error "current index should be $cur_rec1 not $cur_rec2"
16096
16097         echo "verifying users from this test are deregistered"
16098         changelog_deregister || error "changelog_deregister failed"
16099         changelog_users $SINGLEMDS | grep -q $cl_user &&
16100                 error "User '$cl_user' still in changelog_users"
16101
16102         # lctl get_param -n mdd.*.changelog_users
16103         # current_index: 144
16104         # ID    index (idle seconds)
16105         # cl3   144   (2) mask=<list>
16106         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16107                 # this is the normal case where all users were deregistered
16108                 # make sure no new records are added when no users are present
16109                 local last_rec1=$(changelog_users $SINGLEMDS |
16110                                   awk '/^current.index:/ { print $NF }')
16111                 touch $DIR/$tdir/chloe
16112                 local last_rec2=$(changelog_users $SINGLEMDS |
16113                                   awk '/^current.index:/ { print $NF }')
16114                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16115                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16116         else
16117                 # any changelog users must be leftovers from a previous test
16118                 changelog_users $SINGLEMDS
16119                 echo "other changelog users; can't verify off"
16120         fi
16121 }
16122 run_test 160a "changelog sanity"
16123
16124 test_160b() { # LU-3587
16125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16126         remote_mds_nodsh && skip "remote MDS with nodsh"
16127         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16128                 skip "Need MDS version at least 2.2.0"
16129
16130         changelog_register || error "changelog_register failed"
16131         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16132         changelog_users $SINGLEMDS | grep -q $cl_user ||
16133                 error "User '$cl_user' not found in changelog_users"
16134
16135         local longname1=$(str_repeat a 255)
16136         local longname2=$(str_repeat b 255)
16137
16138         cd $DIR
16139         echo "creating very long named file"
16140         touch $longname1 || error "create of '$longname1' failed"
16141         echo "renaming very long named file"
16142         mv $longname1 $longname2
16143
16144         changelog_dump | grep RENME | tail -n 5
16145         rm -f $longname2
16146 }
16147 run_test 160b "Verify that very long rename doesn't crash in changelog"
16148
16149 test_160c() {
16150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16151         remote_mds_nodsh && skip "remote MDS with nodsh"
16152
16153         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16154                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16155                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16156                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16157
16158         local rc=0
16159
16160         # Registration step
16161         changelog_register || error "changelog_register failed"
16162
16163         rm -rf $DIR/$tdir
16164         mkdir -p $DIR/$tdir
16165         $MCREATE $DIR/$tdir/foo_160c
16166         changelog_chmask "-TRUNC"
16167         $TRUNCATE $DIR/$tdir/foo_160c 200
16168         changelog_chmask "+TRUNC"
16169         $TRUNCATE $DIR/$tdir/foo_160c 199
16170         changelog_dump | tail -n 5
16171         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16172         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16173 }
16174 run_test 160c "verify that changelog log catch the truncate event"
16175
16176 test_160d() {
16177         remote_mds_nodsh && skip "remote MDS with nodsh"
16178         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16180         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16181                 skip "Need MDS version at least 2.7.60"
16182
16183         # Registration step
16184         changelog_register || error "changelog_register failed"
16185
16186         mkdir -p $DIR/$tdir/migrate_dir
16187         changelog_clear 0 || error "changelog_clear failed"
16188
16189         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16190         changelog_dump | tail -n 5
16191         local migrates=$(changelog_dump | grep -c "MIGRT")
16192         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16193 }
16194 run_test 160d "verify that changelog log catch the migrate event"
16195
16196 test_160e() {
16197         remote_mds_nodsh && skip "remote MDS with nodsh"
16198
16199         # Create a user
16200         changelog_register || error "changelog_register failed"
16201
16202         local MDT0=$(facet_svc $SINGLEMDS)
16203         local rc
16204
16205         # No user (expect fail)
16206         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16207         rc=$?
16208         if [ $rc -eq 0 ]; then
16209                 error "Should fail without user"
16210         elif [ $rc -ne 4 ]; then
16211                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16212         fi
16213
16214         # Delete a future user (expect fail)
16215         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16216         rc=$?
16217         if [ $rc -eq 0 ]; then
16218                 error "Deleted non-existant user cl77"
16219         elif [ $rc -ne 2 ]; then
16220                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16221         fi
16222
16223         # Clear to a bad index (1 billion should be safe)
16224         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16225         rc=$?
16226
16227         if [ $rc -eq 0 ]; then
16228                 error "Successfully cleared to invalid CL index"
16229         elif [ $rc -ne 22 ]; then
16230                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16231         fi
16232 }
16233 run_test 160e "changelog negative testing (should return errors)"
16234
16235 test_160f() {
16236         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16237         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16238                 skip "Need MDS version at least 2.10.56"
16239
16240         local mdts=$(comma_list $(mdts_nodes))
16241
16242         # Create a user
16243         changelog_register || error "first changelog_register failed"
16244         changelog_register || error "second changelog_register failed"
16245         local cl_users
16246         declare -A cl_user1
16247         declare -A cl_user2
16248         local user_rec1
16249         local user_rec2
16250         local i
16251
16252         # generate some changelog records to accumulate on each MDT
16253         # use all_char because created files should be evenly distributed
16254         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16255                 error "test_mkdir $tdir failed"
16256         log "$(date +%s): creating first files"
16257         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16258                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16259                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16260         done
16261
16262         # check changelogs have been generated
16263         local start=$SECONDS
16264         local idle_time=$((MDSCOUNT * 5 + 5))
16265         local nbcl=$(changelog_dump | wc -l)
16266         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16267
16268         for param in "changelog_max_idle_time=$idle_time" \
16269                      "changelog_gc=1" \
16270                      "changelog_min_gc_interval=2" \
16271                      "changelog_min_free_cat_entries=3"; do
16272                 local MDT0=$(facet_svc $SINGLEMDS)
16273                 local var="${param%=*}"
16274                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16275
16276                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16277                 do_nodes $mdts $LCTL set_param mdd.*.$param
16278         done
16279
16280         # force cl_user2 to be idle (1st part), but also cancel the
16281         # cl_user1 records so that it is not evicted later in the test.
16282         local sleep1=$((idle_time / 2))
16283         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16284         sleep $sleep1
16285
16286         # simulate changelog catalog almost full
16287         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16288         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16289
16290         for i in $(seq $MDSCOUNT); do
16291                 cl_users=(${CL_USERS[mds$i]})
16292                 cl_user1[mds$i]="${cl_users[0]}"
16293                 cl_user2[mds$i]="${cl_users[1]}"
16294
16295                 [ -n "${cl_user1[mds$i]}" ] ||
16296                         error "mds$i: no user registered"
16297                 [ -n "${cl_user2[mds$i]}" ] ||
16298                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16299
16300                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16301                 [ -n "$user_rec1" ] ||
16302                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16303                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16304                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16305                 [ -n "$user_rec2" ] ||
16306                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16307                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16308                      "$user_rec1 + 2 == $user_rec2"
16309                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16310                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16311                               "$user_rec1 + 2, but is $user_rec2"
16312                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16313                 [ -n "$user_rec2" ] ||
16314                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16315                 [ $user_rec1 == $user_rec2 ] ||
16316                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16317                               "$user_rec1, but is $user_rec2"
16318         done
16319
16320         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16321         local sleep2=$((idle_time - (SECONDS - start) + 1))
16322         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16323         sleep $sleep2
16324
16325         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16326         # cl_user1 should be OK because it recently processed records.
16327         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16328         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16329                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16330                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16331         done
16332
16333         # ensure gc thread is done
16334         for i in $(mdts_nodes); do
16335                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16336                         error "$i: GC-thread not done"
16337         done
16338
16339         local first_rec
16340         for (( i = 1; i <= MDSCOUNT; i++ )); do
16341                 # check cl_user1 still registered
16342                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16343                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16344                 # check cl_user2 unregistered
16345                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16346                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16347
16348                 # check changelogs are present and starting at $user_rec1 + 1
16349                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16350                 [ -n "$user_rec1" ] ||
16351                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16352                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16353                             awk '{ print $1; exit; }')
16354
16355                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16356                 [ $((user_rec1 + 1)) == $first_rec ] ||
16357                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16358         done
16359 }
16360 run_test 160f "changelog garbage collect (timestamped users)"
16361
16362 test_160g() {
16363         remote_mds_nodsh && skip "remote MDS with nodsh"
16364         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16365                 skip "Need MDS version at least 2.14.55"
16366
16367         local mdts=$(comma_list $(mdts_nodes))
16368
16369         # Create a user
16370         changelog_register || error "first changelog_register failed"
16371         changelog_register || error "second changelog_register failed"
16372         local cl_users
16373         declare -A cl_user1
16374         declare -A cl_user2
16375         local user_rec1
16376         local user_rec2
16377         local i
16378
16379         # generate some changelog records to accumulate on each MDT
16380         # use all_char because created files should be evenly distributed
16381         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16382                 error "test_mkdir $tdir failed"
16383         for ((i = 0; i < MDSCOUNT; i++)); do
16384                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16385                         error "create $DIR/$tdir/d$i.1 failed"
16386         done
16387
16388         # check changelogs have been generated
16389         local nbcl=$(changelog_dump | wc -l)
16390         (( $nbcl > 0 )) || error "no changelogs found"
16391
16392         # reduce the max_idle_indexes value to make sure we exceed it
16393         for param in "changelog_max_idle_indexes=2" \
16394                      "changelog_gc=1" \
16395                      "changelog_min_gc_interval=2"; do
16396                 local MDT0=$(facet_svc $SINGLEMDS)
16397                 local var="${param%=*}"
16398                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16399
16400                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16401                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16402                         error "unable to set mdd.*.$param"
16403         done
16404
16405         local start=$SECONDS
16406         for i in $(seq $MDSCOUNT); do
16407                 cl_users=(${CL_USERS[mds$i]})
16408                 cl_user1[mds$i]="${cl_users[0]}"
16409                 cl_user2[mds$i]="${cl_users[1]}"
16410
16411                 [ -n "${cl_user1[mds$i]}" ] ||
16412                         error "mds$i: user1 is not registered"
16413                 [ -n "${cl_user2[mds$i]}" ] ||
16414                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16415
16416                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16417                 [ -n "$user_rec1" ] ||
16418                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16419                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16420                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16421                 [ -n "$user_rec2" ] ||
16422                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16423                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16424                      "$user_rec1 + 2 == $user_rec2"
16425                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16426                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16427                               "expected $user_rec1 + 2, but is $user_rec2"
16428                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16429                 [ -n "$user_rec2" ] ||
16430                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16431                 [ $user_rec1 == $user_rec2 ] ||
16432                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16433                               "expected $user_rec1, but is $user_rec2"
16434         done
16435
16436         # ensure we are past the previous changelog_min_gc_interval set above
16437         local sleep2=$((start + 2 - SECONDS))
16438         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16439         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16440         # cl_user1 should be OK because it recently processed records.
16441         for ((i = 0; i < MDSCOUNT; i++)); do
16442                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16443                         error "create $DIR/$tdir/d$i.3 failed"
16444         done
16445
16446         # ensure gc thread is done
16447         for i in $(mdts_nodes); do
16448                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16449                         error "$i: GC-thread not done"
16450         done
16451
16452         local first_rec
16453         for (( i = 1; i <= MDSCOUNT; i++ )); do
16454                 # check cl_user1 still registered
16455                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16456                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16457                 # check cl_user2 unregistered
16458                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16459                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16460
16461                 # check changelogs are present and starting at $user_rec1 + 1
16462                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16463                 [ -n "$user_rec1" ] ||
16464                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16465                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16466                             awk '{ print $1; exit; }')
16467
16468                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16469                 [ $((user_rec1 + 1)) == $first_rec ] ||
16470                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16471         done
16472 }
16473 run_test 160g "changelog garbage collect on idle records"
16474
16475 test_160h() {
16476         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16477         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16478                 skip "Need MDS version at least 2.10.56"
16479
16480         local mdts=$(comma_list $(mdts_nodes))
16481
16482         # Create a user
16483         changelog_register || error "first changelog_register failed"
16484         changelog_register || error "second changelog_register failed"
16485         local cl_users
16486         declare -A cl_user1
16487         declare -A cl_user2
16488         local user_rec1
16489         local user_rec2
16490         local i
16491
16492         # generate some changelog records to accumulate on each MDT
16493         # use all_char because created files should be evenly distributed
16494         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16495                 error "test_mkdir $tdir failed"
16496         for ((i = 0; i < MDSCOUNT; i++)); do
16497                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16498                         error "create $DIR/$tdir/d$i.1 failed"
16499         done
16500
16501         # check changelogs have been generated
16502         local nbcl=$(changelog_dump | wc -l)
16503         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16504
16505         for param in "changelog_max_idle_time=10" \
16506                      "changelog_gc=1" \
16507                      "changelog_min_gc_interval=2"; do
16508                 local MDT0=$(facet_svc $SINGLEMDS)
16509                 local var="${param%=*}"
16510                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16511
16512                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16513                 do_nodes $mdts $LCTL set_param mdd.*.$param
16514         done
16515
16516         # force cl_user2 to be idle (1st part)
16517         sleep 9
16518
16519         for i in $(seq $MDSCOUNT); do
16520                 cl_users=(${CL_USERS[mds$i]})
16521                 cl_user1[mds$i]="${cl_users[0]}"
16522                 cl_user2[mds$i]="${cl_users[1]}"
16523
16524                 [ -n "${cl_user1[mds$i]}" ] ||
16525                         error "mds$i: no user registered"
16526                 [ -n "${cl_user2[mds$i]}" ] ||
16527                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16528
16529                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16530                 [ -n "$user_rec1" ] ||
16531                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16532                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16533                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16534                 [ -n "$user_rec2" ] ||
16535                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16536                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16537                      "$user_rec1 + 2 == $user_rec2"
16538                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16539                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16540                               "$user_rec1 + 2, but is $user_rec2"
16541                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16542                 [ -n "$user_rec2" ] ||
16543                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16544                 [ $user_rec1 == $user_rec2 ] ||
16545                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16546                               "$user_rec1, but is $user_rec2"
16547         done
16548
16549         # force cl_user2 to be idle (2nd part) and to reach
16550         # changelog_max_idle_time
16551         sleep 2
16552
16553         # force each GC-thread start and block then
16554         # one per MDT/MDD, set fail_val accordingly
16555         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16556         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16557
16558         # generate more changelogs to trigger fail_loc
16559         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16560                 error "create $DIR/$tdir/${tfile}bis failed"
16561
16562         # stop MDT to stop GC-thread, should be done in back-ground as it will
16563         # block waiting for the thread to be released and exit
16564         declare -A stop_pids
16565         for i in $(seq $MDSCOUNT); do
16566                 stop mds$i &
16567                 stop_pids[mds$i]=$!
16568         done
16569
16570         for i in $(mdts_nodes); do
16571                 local facet
16572                 local nb=0
16573                 local facets=$(facets_up_on_host $i)
16574
16575                 for facet in ${facets//,/ }; do
16576                         if [[ $facet == mds* ]]; then
16577                                 nb=$((nb + 1))
16578                         fi
16579                 done
16580                 # ensure each MDS's gc threads are still present and all in "R"
16581                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16582                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16583                         error "$i: expected $nb GC-thread"
16584                 wait_update $i \
16585                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16586                         "R" 20 ||
16587                         error "$i: GC-thread not found in R-state"
16588                 # check umounts of each MDT on MDS have reached kthread_stop()
16589                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16590                         error "$i: expected $nb umount"
16591                 wait_update $i \
16592                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16593                         error "$i: umount not found in D-state"
16594         done
16595
16596         # release all GC-threads
16597         do_nodes $mdts $LCTL set_param fail_loc=0
16598
16599         # wait for MDT stop to complete
16600         for i in $(seq $MDSCOUNT); do
16601                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16602         done
16603
16604         # XXX
16605         # may try to check if any orphan changelog records are present
16606         # via ldiskfs/zfs and llog_reader...
16607
16608         # re-start/mount MDTs
16609         for i in $(seq $MDSCOUNT); do
16610                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16611                         error "Fail to start mds$i"
16612         done
16613
16614         local first_rec
16615         for i in $(seq $MDSCOUNT); do
16616                 # check cl_user1 still registered
16617                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16618                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16619                 # check cl_user2 unregistered
16620                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16621                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16622
16623                 # check changelogs are present and starting at $user_rec1 + 1
16624                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16625                 [ -n "$user_rec1" ] ||
16626                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16627                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16628                             awk '{ print $1; exit; }')
16629
16630                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16631                 [ $((user_rec1 + 1)) == $first_rec ] ||
16632                         error "mds$i: first index should be $user_rec1 + 1, " \
16633                               "but is $first_rec"
16634         done
16635 }
16636 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16637               "during mount"
16638
16639 test_160i() {
16640
16641         local mdts=$(comma_list $(mdts_nodes))
16642
16643         changelog_register || error "first changelog_register failed"
16644
16645         # generate some changelog records to accumulate on each MDT
16646         # use all_char because created files should be evenly distributed
16647         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16648                 error "test_mkdir $tdir failed"
16649         for ((i = 0; i < MDSCOUNT; i++)); do
16650                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16651                         error "create $DIR/$tdir/d$i.1 failed"
16652         done
16653
16654         # check changelogs have been generated
16655         local nbcl=$(changelog_dump | wc -l)
16656         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16657
16658         # simulate race between register and unregister
16659         # XXX as fail_loc is set per-MDS, with DNE configs the race
16660         # simulation will only occur for one MDT per MDS and for the
16661         # others the normal race scenario will take place
16662         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16663         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16664         do_nodes $mdts $LCTL set_param fail_val=1
16665
16666         # unregister 1st user
16667         changelog_deregister &
16668         local pid1=$!
16669         # wait some time for deregister work to reach race rdv
16670         sleep 2
16671         # register 2nd user
16672         changelog_register || error "2nd user register failed"
16673
16674         wait $pid1 || error "1st user deregister failed"
16675
16676         local i
16677         local last_rec
16678         declare -A LAST_REC
16679         for i in $(seq $MDSCOUNT); do
16680                 if changelog_users mds$i | grep "^cl"; then
16681                         # make sure new records are added with one user present
16682                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16683                                           awk '/^current.index:/ { print $NF }')
16684                 else
16685                         error "mds$i has no user registered"
16686                 fi
16687         done
16688
16689         # generate more changelog records to accumulate on each MDT
16690         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16691                 error "create $DIR/$tdir/${tfile}bis failed"
16692
16693         for i in $(seq $MDSCOUNT); do
16694                 last_rec=$(changelog_users $SINGLEMDS |
16695                            awk '/^current.index:/ { print $NF }')
16696                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16697                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16698                         error "changelogs are off on mds$i"
16699         done
16700 }
16701 run_test 160i "changelog user register/unregister race"
16702
16703 test_160j() {
16704         remote_mds_nodsh && skip "remote MDS with nodsh"
16705         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16706                 skip "Need MDS version at least 2.12.56"
16707
16708         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16709         stack_trap "umount $MOUNT2" EXIT
16710
16711         changelog_register || error "first changelog_register failed"
16712         stack_trap "changelog_deregister" EXIT
16713
16714         # generate some changelog
16715         # use all_char because created files should be evenly distributed
16716         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16717                 error "mkdir $tdir failed"
16718         for ((i = 0; i < MDSCOUNT; i++)); do
16719                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16720                         error "create $DIR/$tdir/d$i.1 failed"
16721         done
16722
16723         # open the changelog device
16724         exec 3>/dev/changelog-$FSNAME-MDT0000
16725         stack_trap "exec 3>&-" EXIT
16726         exec 4</dev/changelog-$FSNAME-MDT0000
16727         stack_trap "exec 4<&-" EXIT
16728
16729         # umount the first lustre mount
16730         umount $MOUNT
16731         stack_trap "mount_client $MOUNT" EXIT
16732
16733         # read changelog, which may or may not fail, but should not crash
16734         cat <&4 >/dev/null
16735
16736         # clear changelog
16737         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16738         changelog_users $SINGLEMDS | grep -q $cl_user ||
16739                 error "User $cl_user not found in changelog_users"
16740
16741         printf 'clear:'$cl_user':0' >&3
16742 }
16743 run_test 160j "client can be umounted while its chanangelog is being used"
16744
16745 test_160k() {
16746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16747         remote_mds_nodsh && skip "remote MDS with nodsh"
16748
16749         mkdir -p $DIR/$tdir/1/1
16750
16751         changelog_register || error "changelog_register failed"
16752         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16753
16754         changelog_users $SINGLEMDS | grep -q $cl_user ||
16755                 error "User '$cl_user' not found in changelog_users"
16756 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16757         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16758         rmdir $DIR/$tdir/1/1 & sleep 1
16759         mkdir $DIR/$tdir/2
16760         touch $DIR/$tdir/2/2
16761         rm -rf $DIR/$tdir/2
16762
16763         wait
16764         sleep 4
16765
16766         changelog_dump | grep rmdir || error "rmdir not recorded"
16767 }
16768 run_test 160k "Verify that changelog records are not lost"
16769
16770 # Verifies that a file passed as a parameter has recently had an operation
16771 # performed on it that has generated an MTIME changelog which contains the
16772 # correct parent FID. As files might reside on a different MDT from the
16773 # parent directory in DNE configurations, the FIDs are translated to paths
16774 # before being compared, which should be identical
16775 compare_mtime_changelog() {
16776         local file="${1}"
16777         local mdtidx
16778         local mtime
16779         local cl_fid
16780         local pdir
16781         local dir
16782
16783         mdtidx=$($LFS getstripe --mdt-index $file)
16784         mdtidx=$(printf "%04x" $mdtidx)
16785
16786         # Obtain the parent FID from the MTIME changelog
16787         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16788         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16789
16790         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16791         [ -z "$cl_fid" ] && error "parent FID not present"
16792
16793         # Verify that the path for the parent FID is the same as the path for
16794         # the test directory
16795         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16796
16797         dir=$(dirname $1)
16798
16799         [[ "${pdir%/}" == "$dir" ]] ||
16800                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16801 }
16802
16803 test_160l() {
16804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16805
16806         remote_mds_nodsh && skip "remote MDS with nodsh"
16807         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16808                 skip "Need MDS version at least 2.13.55"
16809
16810         local cl_user
16811
16812         changelog_register || error "changelog_register failed"
16813         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16814
16815         changelog_users $SINGLEMDS | grep -q $cl_user ||
16816                 error "User '$cl_user' not found in changelog_users"
16817
16818         # Clear some types so that MTIME changelogs are generated
16819         changelog_chmask "-CREAT"
16820         changelog_chmask "-CLOSE"
16821
16822         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16823
16824         # Test CL_MTIME during setattr
16825         touch $DIR/$tdir/$tfile
16826         compare_mtime_changelog $DIR/$tdir/$tfile
16827
16828         # Test CL_MTIME during close
16829         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16830         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16831 }
16832 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16833
16834 test_160m() {
16835         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16836         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16837                 skip "Need MDS version at least 2.14.51"
16838         local cl_users
16839         local cl_user1
16840         local cl_user2
16841         local pid1
16842
16843         # Create a user
16844         changelog_register || error "first changelog_register failed"
16845         changelog_register || error "second changelog_register failed"
16846
16847         cl_users=(${CL_USERS[mds1]})
16848         cl_user1="${cl_users[0]}"
16849         cl_user2="${cl_users[1]}"
16850         # generate some changelog records to accumulate on MDT0
16851         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16852         createmany -m $DIR/$tdir/$tfile 50 ||
16853                 error "create $DIR/$tdir/$tfile failed"
16854         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16855         rm -f $DIR/$tdir
16856
16857         # check changelogs have been generated
16858         local nbcl=$(changelog_dump | wc -l)
16859         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16860
16861 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16862         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16863
16864         __changelog_clear mds1 $cl_user1 +10
16865         __changelog_clear mds1 $cl_user2 0 &
16866         pid1=$!
16867         sleep 2
16868         __changelog_clear mds1 $cl_user1 0 ||
16869                 error "fail to cancel record for $cl_user1"
16870         wait $pid1
16871         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16872 }
16873 run_test 160m "Changelog clear race"
16874
16875 test_160n() {
16876         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16877         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16878                 skip "Need MDS version at least 2.14.51"
16879         local cl_users
16880         local cl_user1
16881         local cl_user2
16882         local pid1
16883         local first_rec
16884         local last_rec=0
16885
16886         # Create a user
16887         changelog_register || error "first changelog_register failed"
16888
16889         cl_users=(${CL_USERS[mds1]})
16890         cl_user1="${cl_users[0]}"
16891
16892         # generate some changelog records to accumulate on MDT0
16893         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16894         first_rec=$(changelog_users $SINGLEMDS |
16895                         awk '/^current.index:/ { print $NF }')
16896         while (( last_rec < (( first_rec + 65000)) )); do
16897                 createmany -m $DIR/$tdir/$tfile 10000 ||
16898                         error "create $DIR/$tdir/$tfile failed"
16899
16900                 for i in $(seq 0 10000); do
16901                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16902                                 > /dev/null
16903                 done
16904
16905                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16906                         error "unlinkmany failed unlink"
16907                 last_rec=$(changelog_users $SINGLEMDS |
16908                         awk '/^current.index:/ { print $NF }')
16909                 echo last record $last_rec
16910                 (( last_rec == 0 )) && error "no changelog found"
16911         done
16912
16913 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16914         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16915
16916         __changelog_clear mds1 $cl_user1 0 &
16917         pid1=$!
16918         sleep 2
16919         __changelog_clear mds1 $cl_user1 0 ||
16920                 error "fail to cancel record for $cl_user1"
16921         wait $pid1
16922         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16923 }
16924 run_test 160n "Changelog destroy race"
16925
16926 test_160o() {
16927         local mdt="$(facet_svc $SINGLEMDS)"
16928
16929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16930         remote_mds_nodsh && skip "remote MDS with nodsh"
16931         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16932                 skip "Need MDS version at least 2.14.52"
16933
16934         changelog_register --user test_160o -m unlnk+close+open ||
16935                 error "changelog_register failed"
16936
16937         do_facet $SINGLEMDS $LCTL --device $mdt \
16938                                 changelog_register -u "Tt3_-#" &&
16939                 error "bad symbols in name should fail"
16940
16941         do_facet $SINGLEMDS $LCTL --device $mdt \
16942                                 changelog_register -u test_160o &&
16943                 error "the same name registration should fail"
16944
16945         do_facet $SINGLEMDS $LCTL --device $mdt \
16946                         changelog_register -u test_160toolongname &&
16947                 error "too long name registration should fail"
16948
16949         changelog_chmask "MARK+HSM"
16950         lctl get_param mdd.*.changelog*mask
16951         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16952         changelog_users $SINGLEMDS | grep -q $cl_user ||
16953                 error "User $cl_user not found in changelog_users"
16954         #verify username
16955         echo $cl_user | grep -q test_160o ||
16956                 error "User $cl_user has no specific name 'test160o'"
16957
16958         # change something
16959         changelog_clear 0 || error "changelog_clear failed"
16960         # generate some changelog records to accumulate on MDT0
16961         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16962         touch $DIR/$tdir/$tfile                 # open 1
16963
16964         OPENS=$(changelog_dump | grep -c "OPEN")
16965         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16966
16967         # must be no MKDIR it wasn't set as user mask
16968         MKDIR=$(changelog_dump | grep -c "MKDIR")
16969         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16970
16971         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16972                                 mdd.$mdt.changelog_current_mask -n)
16973         # register maskless user
16974         changelog_register || error "changelog_register failed"
16975         # effective mask should be not changed because it is not minimal
16976         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16977                                 mdd.$mdt.changelog_current_mask -n)
16978         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16979         # set server mask to minimal value
16980         changelog_chmask "MARK"
16981         # check effective mask again, should be treated as DEFMASK now
16982         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16983                                 mdd.$mdt.changelog_current_mask -n)
16984         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16985
16986         do_facet $SINGLEMDS $LCTL --device $mdt \
16987                                 changelog_deregister -u test_160o ||
16988                 error "cannot deregister by name"
16989 }
16990 run_test 160o "changelog user name and mask"
16991
16992 test_160p() {
16993         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16994         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16995                 skip "Need MDS version at least 2.14.51"
16996         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16997         local cl_users
16998         local cl_user1
16999         local entry_count
17000
17001         # Create a user
17002         changelog_register || error "first changelog_register failed"
17003
17004         cl_users=(${CL_USERS[mds1]})
17005         cl_user1="${cl_users[0]}"
17006
17007         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17008         createmany -m $DIR/$tdir/$tfile 50 ||
17009                 error "create $DIR/$tdir/$tfile failed"
17010         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17011         rm -rf $DIR/$tdir
17012
17013         # check changelogs have been generated
17014         entry_count=$(changelog_dump | wc -l)
17015         ((entry_count != 0)) || error "no changelog entries found"
17016
17017         # remove changelog_users and check that orphan entries are removed
17018         stop mds1
17019         local dev=$(mdsdevname 1)
17020         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17021         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17022         entry_count=$(changelog_dump | wc -l)
17023         ((entry_count == 0)) ||
17024                 error "found $entry_count changelog entries, expected none"
17025 }
17026 run_test 160p "Changelog orphan cleanup with no users"
17027
17028 test_160q() {
17029         local mdt="$(facet_svc $SINGLEMDS)"
17030         local clu
17031
17032         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17033         remote_mds_nodsh && skip "remote MDS with nodsh"
17034         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17035                 skip "Need MDS version at least 2.14.54"
17036
17037         # set server mask to minimal value like server init does
17038         changelog_chmask "MARK"
17039         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17040                 error "changelog_register failed"
17041         # check effective mask again, should be treated as DEFMASK now
17042         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17043                                 mdd.$mdt.changelog_current_mask -n)
17044         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17045                 error "changelog_deregister failed"
17046         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17047 }
17048 run_test 160q "changelog effective mask is DEFMASK if not set"
17049
17050 test_160s() {
17051         remote_mds_nodsh && skip "remote MDS with nodsh"
17052         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17053                 skip "Need MDS version at least 2.14.55"
17054
17055         local mdts=$(comma_list $(mdts_nodes))
17056
17057         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17058         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17059                                        fail_val=$((24 * 3600 * 10))
17060
17061         # Create a user which is 10 days old
17062         changelog_register || error "first changelog_register failed"
17063         local cl_users
17064         declare -A cl_user1
17065         local i
17066
17067         # generate some changelog records to accumulate on each MDT
17068         # use all_char because created files should be evenly distributed
17069         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17070                 error "test_mkdir $tdir failed"
17071         for ((i = 0; i < MDSCOUNT; i++)); do
17072                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17073                         error "create $DIR/$tdir/d$i.1 failed"
17074         done
17075
17076         # check changelogs have been generated
17077         local nbcl=$(changelog_dump | wc -l)
17078         (( nbcl > 0 )) || error "no changelogs found"
17079
17080         # reduce the max_idle_indexes value to make sure we exceed it
17081         for param in "changelog_max_idle_indexes=2097446912" \
17082                      "changelog_max_idle_time=2592000" \
17083                      "changelog_gc=1" \
17084                      "changelog_min_gc_interval=2"; do
17085                 local MDT0=$(facet_svc $SINGLEMDS)
17086                 local var="${param%=*}"
17087                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17088
17089                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17090                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17091                         error "unable to set mdd.*.$param"
17092         done
17093
17094         local start=$SECONDS
17095         for i in $(seq $MDSCOUNT); do
17096                 cl_users=(${CL_USERS[mds$i]})
17097                 cl_user1[mds$i]="${cl_users[0]}"
17098
17099                 [[ -n "${cl_user1[mds$i]}" ]] ||
17100                         error "mds$i: no user registered"
17101         done
17102
17103         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17104         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17105
17106         # ensure we are past the previous changelog_min_gc_interval set above
17107         local sleep2=$((start + 2 - SECONDS))
17108         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17109
17110         # Generate one more changelog to trigger GC
17111         for ((i = 0; i < MDSCOUNT; i++)); do
17112                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17113                         error "create $DIR/$tdir/d$i.3 failed"
17114         done
17115
17116         # ensure gc thread is done
17117         for node in $(mdts_nodes); do
17118                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17119                         error "$node: GC-thread not done"
17120         done
17121
17122         do_nodes $mdts $LCTL set_param fail_loc=0
17123
17124         for (( i = 1; i <= MDSCOUNT; i++ )); do
17125                 # check cl_user1 is purged
17126                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17127                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17128         done
17129         return 0
17130 }
17131 run_test 160s "changelog garbage collect on idle records * time"
17132
17133 test_161a() {
17134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17135
17136         test_mkdir -c1 $DIR/$tdir
17137         cp /etc/hosts $DIR/$tdir/$tfile
17138         test_mkdir -c1 $DIR/$tdir/foo1
17139         test_mkdir -c1 $DIR/$tdir/foo2
17140         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17141         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17142         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17143         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17144         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17145         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17146                 $LFS fid2path $DIR $FID
17147                 error "bad link ea"
17148         fi
17149         # middle
17150         rm $DIR/$tdir/foo2/zachary
17151         # last
17152         rm $DIR/$tdir/foo2/thor
17153         # first
17154         rm $DIR/$tdir/$tfile
17155         # rename
17156         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17157         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17158                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17159         rm $DIR/$tdir/foo2/maggie
17160
17161         # overflow the EA
17162         local longname=$tfile.avg_len_is_thirty_two_
17163         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17164                 error_noexit 'failed to unlink many hardlinks'" EXIT
17165         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17166                 error "failed to hardlink many files"
17167         links=$($LFS fid2path $DIR $FID | wc -l)
17168         echo -n "${links}/1000 links in link EA"
17169         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17170 }
17171 run_test 161a "link ea sanity"
17172
17173 test_161b() {
17174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17175         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17176
17177         local MDTIDX=1
17178         local remote_dir=$DIR/$tdir/remote_dir
17179
17180         mkdir -p $DIR/$tdir
17181         $LFS mkdir -i $MDTIDX $remote_dir ||
17182                 error "create remote directory failed"
17183
17184         cp /etc/hosts $remote_dir/$tfile
17185         mkdir -p $remote_dir/foo1
17186         mkdir -p $remote_dir/foo2
17187         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17188         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17189         ln $remote_dir/$tfile $remote_dir/foo1/luna
17190         ln $remote_dir/$tfile $remote_dir/foo2/thor
17191
17192         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17193                      tr -d ']')
17194         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17195                 $LFS fid2path $DIR $FID
17196                 error "bad link ea"
17197         fi
17198         # middle
17199         rm $remote_dir/foo2/zachary
17200         # last
17201         rm $remote_dir/foo2/thor
17202         # first
17203         rm $remote_dir/$tfile
17204         # rename
17205         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17206         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17207         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17208                 $LFS fid2path $DIR $FID
17209                 error "bad link rename"
17210         fi
17211         rm $remote_dir/foo2/maggie
17212
17213         # overflow the EA
17214         local longname=filename_avg_len_is_thirty_two_
17215         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17216                 error "failed to hardlink many files"
17217         links=$($LFS fid2path $DIR $FID | wc -l)
17218         echo -n "${links}/1000 links in link EA"
17219         [[ ${links} -gt 60 ]] ||
17220                 error "expected at least 60 links in link EA"
17221         unlinkmany $remote_dir/foo2/$longname 1000 ||
17222         error "failed to unlink many hardlinks"
17223 }
17224 run_test 161b "link ea sanity under remote directory"
17225
17226 test_161c() {
17227         remote_mds_nodsh && skip "remote MDS with nodsh"
17228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17229         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17230                 skip "Need MDS version at least 2.1.5"
17231
17232         # define CLF_RENAME_LAST 0x0001
17233         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17234         changelog_register || error "changelog_register failed"
17235
17236         rm -rf $DIR/$tdir
17237         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17238         touch $DIR/$tdir/foo_161c
17239         touch $DIR/$tdir/bar_161c
17240         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17241         changelog_dump | grep RENME | tail -n 5
17242         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17243         changelog_clear 0 || error "changelog_clear failed"
17244         if [ x$flags != "x0x1" ]; then
17245                 error "flag $flags is not 0x1"
17246         fi
17247
17248         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17249         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17250         touch $DIR/$tdir/foo_161c
17251         touch $DIR/$tdir/bar_161c
17252         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17253         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17254         changelog_dump | grep RENME | tail -n 5
17255         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17256         changelog_clear 0 || error "changelog_clear failed"
17257         if [ x$flags != "x0x0" ]; then
17258                 error "flag $flags is not 0x0"
17259         fi
17260         echo "rename overwrite a target having nlink > 1," \
17261                 "changelog record has flags of $flags"
17262
17263         # rename doesn't overwrite a target (changelog flag 0x0)
17264         touch $DIR/$tdir/foo_161c
17265         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17266         changelog_dump | grep RENME | tail -n 5
17267         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17268         changelog_clear 0 || error "changelog_clear failed"
17269         if [ x$flags != "x0x0" ]; then
17270                 error "flag $flags is not 0x0"
17271         fi
17272         echo "rename doesn't overwrite a target," \
17273                 "changelog record has flags of $flags"
17274
17275         # define CLF_UNLINK_LAST 0x0001
17276         # unlink a file having nlink = 1 (changelog flag 0x1)
17277         rm -f $DIR/$tdir/foo2_161c
17278         changelog_dump | grep UNLNK | tail -n 5
17279         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17280         changelog_clear 0 || error "changelog_clear failed"
17281         if [ x$flags != "x0x1" ]; then
17282                 error "flag $flags is not 0x1"
17283         fi
17284         echo "unlink a file having nlink = 1," \
17285                 "changelog record has flags of $flags"
17286
17287         # unlink a file having nlink > 1 (changelog flag 0x0)
17288         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17289         rm -f $DIR/$tdir/foobar_161c
17290         changelog_dump | grep UNLNK | tail -n 5
17291         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17292         changelog_clear 0 || error "changelog_clear failed"
17293         if [ x$flags != "x0x0" ]; then
17294                 error "flag $flags is not 0x0"
17295         fi
17296         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17297 }
17298 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17299
17300 test_161d() {
17301         remote_mds_nodsh && skip "remote MDS with nodsh"
17302         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17303
17304         local pid
17305         local fid
17306
17307         changelog_register || error "changelog_register failed"
17308
17309         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17310         # interfer with $MOUNT/.lustre/fid/ access
17311         mkdir $DIR/$tdir
17312         [[ $? -eq 0 ]] || error "mkdir failed"
17313
17314         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17315         $LCTL set_param fail_loc=0x8000140c
17316         # 5s pause
17317         $LCTL set_param fail_val=5
17318
17319         # create file
17320         echo foofoo > $DIR/$tdir/$tfile &
17321         pid=$!
17322
17323         # wait for create to be delayed
17324         sleep 2
17325
17326         ps -p $pid
17327         [[ $? -eq 0 ]] || error "create should be blocked"
17328
17329         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17330         stack_trap "rm -f $tempfile"
17331         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17332         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17333         # some delay may occur during ChangeLog publishing and file read just
17334         # above, that could allow file write to happen finally
17335         [[ -s $tempfile ]] && echo "file should be empty"
17336
17337         $LCTL set_param fail_loc=0
17338
17339         wait $pid
17340         [[ $? -eq 0 ]] || error "create failed"
17341 }
17342 run_test 161d "create with concurrent .lustre/fid access"
17343
17344 check_path() {
17345         local expected="$1"
17346         shift
17347         local fid="$2"
17348
17349         local path
17350         path=$($LFS fid2path "$@")
17351         local rc=$?
17352
17353         if [ $rc -ne 0 ]; then
17354                 error "path looked up of '$expected' failed: rc=$rc"
17355         elif [ "$path" != "$expected" ]; then
17356                 error "path looked up '$path' instead of '$expected'"
17357         else
17358                 echo "FID '$fid' resolves to path '$path' as expected"
17359         fi
17360 }
17361
17362 test_162a() { # was test_162
17363         test_mkdir -p -c1 $DIR/$tdir/d2
17364         touch $DIR/$tdir/d2/$tfile
17365         touch $DIR/$tdir/d2/x1
17366         touch $DIR/$tdir/d2/x2
17367         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17368         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17369         # regular file
17370         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17371         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17372
17373         # softlink
17374         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17375         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17376         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17377
17378         # softlink to wrong file
17379         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17380         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17381         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17382
17383         # hardlink
17384         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17385         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17386         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17387         # fid2path dir/fsname should both work
17388         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17389         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17390
17391         # hardlink count: check that there are 2 links
17392         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17393         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17394
17395         # hardlink indexing: remove the first link
17396         rm $DIR/$tdir/d2/p/q/r/hlink
17397         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17398 }
17399 run_test 162a "path lookup sanity"
17400
17401 test_162b() {
17402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17404
17405         mkdir $DIR/$tdir
17406         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17407                                 error "create striped dir failed"
17408
17409         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17410                                         tail -n 1 | awk '{print $2}')
17411         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17412
17413         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17414         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17415
17416         # regular file
17417         for ((i=0;i<5;i++)); do
17418                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17419                         error "get fid for f$i failed"
17420                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17421
17422                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17423                         error "get fid for d$i failed"
17424                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17425         done
17426
17427         return 0
17428 }
17429 run_test 162b "striped directory path lookup sanity"
17430
17431 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17432 test_162c() {
17433         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17434                 skip "Need MDS version at least 2.7.51"
17435
17436         local lpath=$tdir.local
17437         local rpath=$tdir.remote
17438
17439         test_mkdir $DIR/$lpath
17440         test_mkdir $DIR/$rpath
17441
17442         for ((i = 0; i <= 101; i++)); do
17443                 lpath="$lpath/$i"
17444                 mkdir $DIR/$lpath
17445                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17446                         error "get fid for local directory $DIR/$lpath failed"
17447                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17448
17449                 rpath="$rpath/$i"
17450                 test_mkdir $DIR/$rpath
17451                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17452                         error "get fid for remote directory $DIR/$rpath failed"
17453                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17454         done
17455
17456         return 0
17457 }
17458 run_test 162c "fid2path works with paths 100 or more directories deep"
17459
17460 oalr_event_count() {
17461         local event="${1}"
17462         local trace="${2}"
17463
17464         awk -v name="${FSNAME}-OST0000" \
17465             -v event="${event}" \
17466             '$1 == "TRACE" && $2 == event && $3 == name' \
17467             "${trace}" |
17468         wc -l
17469 }
17470
17471 oalr_expect_event_count() {
17472         local event="${1}"
17473         local trace="${2}"
17474         local expect="${3}"
17475         local count
17476
17477         count=$(oalr_event_count "${event}" "${trace}")
17478         if ((count == expect)); then
17479                 return 0
17480         fi
17481
17482         error_noexit "${event} event count was '${count}', expected ${expect}"
17483         cat "${trace}" >&2
17484         exit 1
17485 }
17486
17487 cleanup_165() {
17488         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17489         stop ost1
17490         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17491 }
17492
17493 setup_165() {
17494         sync # Flush previous IOs so we can count log entries.
17495         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17496         stack_trap cleanup_165 EXIT
17497 }
17498
17499 test_165a() {
17500         local trace="/tmp/${tfile}.trace"
17501         local rc
17502         local count
17503
17504         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17505                 skip "OFD access log unsupported"
17506
17507         setup_165
17508         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17509         sleep 5
17510
17511         do_facet ost1 ofd_access_log_reader --list
17512         stop ost1
17513
17514         do_facet ost1 killall -TERM ofd_access_log_reader
17515         wait
17516         rc=$?
17517
17518         if ((rc != 0)); then
17519                 error "ofd_access_log_reader exited with rc = '${rc}'"
17520         fi
17521
17522         # Parse trace file for discovery events:
17523         oalr_expect_event_count alr_log_add "${trace}" 1
17524         oalr_expect_event_count alr_log_eof "${trace}" 1
17525         oalr_expect_event_count alr_log_free "${trace}" 1
17526 }
17527 run_test 165a "ofd access log discovery"
17528
17529 test_165b() {
17530         local trace="/tmp/${tfile}.trace"
17531         local file="${DIR}/${tfile}"
17532         local pfid1
17533         local pfid2
17534         local -a entry
17535         local rc
17536         local count
17537         local size
17538         local flags
17539
17540         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17541                 skip "OFD access log unsupported"
17542
17543         setup_165
17544         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17545         sleep 5
17546
17547         do_facet ost1 ofd_access_log_reader --list
17548
17549         lfs setstripe -c 1 -i 0 "${file}"
17550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17551                 error "cannot create '${file}'"
17552
17553         sleep 5
17554         do_facet ost1 killall -TERM ofd_access_log_reader
17555         wait
17556         rc=$?
17557
17558         if ((rc != 0)); then
17559                 error "ofd_access_log_reader exited with rc = '${rc}'"
17560         fi
17561
17562         oalr_expect_event_count alr_log_entry "${trace}" 1
17563
17564         pfid1=$($LFS path2fid "${file}")
17565
17566         # 1     2             3   4    5     6   7    8    9     10
17567         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17568         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17569
17570         echo "entry = '${entry[*]}'" >&2
17571
17572         pfid2=${entry[4]}
17573         if [[ "${pfid1}" != "${pfid2}" ]]; then
17574                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17575         fi
17576
17577         size=${entry[8]}
17578         if ((size != 1048576)); then
17579                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17580         fi
17581
17582         flags=${entry[10]}
17583         if [[ "${flags}" != "w" ]]; then
17584                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17585         fi
17586
17587         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17588         sleep 5
17589
17590         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17591                 error "cannot read '${file}'"
17592         sleep 5
17593
17594         do_facet ost1 killall -TERM ofd_access_log_reader
17595         wait
17596         rc=$?
17597
17598         if ((rc != 0)); then
17599                 error "ofd_access_log_reader exited with rc = '${rc}'"
17600         fi
17601
17602         oalr_expect_event_count alr_log_entry "${trace}" 1
17603
17604         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17605         echo "entry = '${entry[*]}'" >&2
17606
17607         pfid2=${entry[4]}
17608         if [[ "${pfid1}" != "${pfid2}" ]]; then
17609                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17610         fi
17611
17612         size=${entry[8]}
17613         if ((size != 524288)); then
17614                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17615         fi
17616
17617         flags=${entry[10]}
17618         if [[ "${flags}" != "r" ]]; then
17619                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17620         fi
17621 }
17622 run_test 165b "ofd access log entries are produced and consumed"
17623
17624 test_165c() {
17625         local trace="/tmp/${tfile}.trace"
17626         local file="${DIR}/${tdir}/${tfile}"
17627
17628         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17629                 skip "OFD access log unsupported"
17630
17631         test_mkdir "${DIR}/${tdir}"
17632
17633         setup_165
17634         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17635         sleep 5
17636
17637         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17638
17639         # 4096 / 64 = 64. Create twice as many entries.
17640         for ((i = 0; i < 128; i++)); do
17641                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17642                         error "cannot create file"
17643         done
17644
17645         sync
17646
17647         do_facet ost1 killall -TERM ofd_access_log_reader
17648         wait
17649         rc=$?
17650         if ((rc != 0)); then
17651                 error "ofd_access_log_reader exited with rc = '${rc}'"
17652         fi
17653
17654         unlinkmany  "${file}-%d" 128
17655 }
17656 run_test 165c "full ofd access logs do not block IOs"
17657
17658 oal_get_read_count() {
17659         local stats="$1"
17660
17661         # STATS lustre-OST0001 alr_read_count 1
17662
17663         do_facet ost1 cat "${stats}" |
17664         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17665              END { print count; }'
17666 }
17667
17668 oal_expect_read_count() {
17669         local stats="$1"
17670         local count
17671         local expect="$2"
17672
17673         # Ask ofd_access_log_reader to write stats.
17674         do_facet ost1 killall -USR1 ofd_access_log_reader
17675
17676         # Allow some time for things to happen.
17677         sleep 1
17678
17679         count=$(oal_get_read_count "${stats}")
17680         if ((count == expect)); then
17681                 return 0
17682         fi
17683
17684         error_noexit "bad read count, got ${count}, expected ${expect}"
17685         do_facet ost1 cat "${stats}" >&2
17686         exit 1
17687 }
17688
17689 test_165d() {
17690         local stats="/tmp/${tfile}.stats"
17691         local file="${DIR}/${tdir}/${tfile}"
17692         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17693
17694         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17695                 skip "OFD access log unsupported"
17696
17697         test_mkdir "${DIR}/${tdir}"
17698
17699         setup_165
17700         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17701         sleep 5
17702
17703         lfs setstripe -c 1 -i 0 "${file}"
17704
17705         do_facet ost1 lctl set_param "${param}=rw"
17706         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17707                 error "cannot create '${file}'"
17708         oal_expect_read_count "${stats}" 1
17709
17710         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17711                 error "cannot read '${file}'"
17712         oal_expect_read_count "${stats}" 2
17713
17714         do_facet ost1 lctl set_param "${param}=r"
17715         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17716                 error "cannot create '${file}'"
17717         oal_expect_read_count "${stats}" 2
17718
17719         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17720                 error "cannot read '${file}'"
17721         oal_expect_read_count "${stats}" 3
17722
17723         do_facet ost1 lctl set_param "${param}=w"
17724         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17725                 error "cannot create '${file}'"
17726         oal_expect_read_count "${stats}" 4
17727
17728         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17729                 error "cannot read '${file}'"
17730         oal_expect_read_count "${stats}" 4
17731
17732         do_facet ost1 lctl set_param "${param}=0"
17733         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17734                 error "cannot create '${file}'"
17735         oal_expect_read_count "${stats}" 4
17736
17737         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17738                 error "cannot read '${file}'"
17739         oal_expect_read_count "${stats}" 4
17740
17741         do_facet ost1 killall -TERM ofd_access_log_reader
17742         wait
17743         rc=$?
17744         if ((rc != 0)); then
17745                 error "ofd_access_log_reader exited with rc = '${rc}'"
17746         fi
17747 }
17748 run_test 165d "ofd_access_log mask works"
17749
17750 test_165e() {
17751         local stats="/tmp/${tfile}.stats"
17752         local file0="${DIR}/${tdir}-0/${tfile}"
17753         local file1="${DIR}/${tdir}-1/${tfile}"
17754
17755         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17756                 skip "OFD access log unsupported"
17757
17758         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17759
17760         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17761         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17762
17763         lfs setstripe -c 1 -i 0 "${file0}"
17764         lfs setstripe -c 1 -i 0 "${file1}"
17765
17766         setup_165
17767         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17768         sleep 5
17769
17770         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17771                 error "cannot create '${file0}'"
17772         sync
17773         oal_expect_read_count "${stats}" 0
17774
17775         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17776                 error "cannot create '${file1}'"
17777         sync
17778         oal_expect_read_count "${stats}" 1
17779
17780         do_facet ost1 killall -TERM ofd_access_log_reader
17781         wait
17782         rc=$?
17783         if ((rc != 0)); then
17784                 error "ofd_access_log_reader exited with rc = '${rc}'"
17785         fi
17786 }
17787 run_test 165e "ofd_access_log MDT index filter works"
17788
17789 test_165f() {
17790         local trace="/tmp/${tfile}.trace"
17791         local rc
17792         local count
17793
17794         setup_165
17795         do_facet ost1 timeout 60 ofd_access_log_reader \
17796                 --exit-on-close --debug=- --trace=- > "${trace}" &
17797         sleep 5
17798         stop ost1
17799
17800         wait
17801         rc=$?
17802
17803         if ((rc != 0)); then
17804                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17805                 cat "${trace}"
17806                 exit 1
17807         fi
17808 }
17809 run_test 165f "ofd_access_log_reader --exit-on-close works"
17810
17811 test_169() {
17812         # do directio so as not to populate the page cache
17813         log "creating a 10 Mb file"
17814         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17815                 error "multiop failed while creating a file"
17816         log "starting reads"
17817         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17818         log "truncating the file"
17819         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17820                 error "multiop failed while truncating the file"
17821         log "killing dd"
17822         kill %+ || true # reads might have finished
17823         echo "wait until dd is finished"
17824         wait
17825         log "removing the temporary file"
17826         rm -rf $DIR/$tfile || error "tmp file removal failed"
17827 }
17828 run_test 169 "parallel read and truncate should not deadlock"
17829
17830 test_170() {
17831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17832
17833         $LCTL clear     # bug 18514
17834         $LCTL debug_daemon start $TMP/${tfile}_log_good
17835         touch $DIR/$tfile
17836         $LCTL debug_daemon stop
17837         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17838                 error "sed failed to read log_good"
17839
17840         $LCTL debug_daemon start $TMP/${tfile}_log_good
17841         rm -rf $DIR/$tfile
17842         $LCTL debug_daemon stop
17843
17844         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17845                error "lctl df log_bad failed"
17846
17847         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17848         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17849
17850         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17851         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17852
17853         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17854                 error "bad_line good_line1 good_line2 are empty"
17855
17856         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17857         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17858         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17859
17860         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17861         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17862         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17863
17864         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17865                 error "bad_line_new good_line_new are empty"
17866
17867         local expected_good=$((good_line1 + good_line2*2))
17868
17869         rm -f $TMP/${tfile}*
17870         # LU-231, short malformed line may not be counted into bad lines
17871         if [ $bad_line -ne $bad_line_new ] &&
17872                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17873                 error "expected $bad_line bad lines, but got $bad_line_new"
17874                 return 1
17875         fi
17876
17877         if [ $expected_good -ne $good_line_new ]; then
17878                 error "expected $expected_good good lines, but got $good_line_new"
17879                 return 2
17880         fi
17881         true
17882 }
17883 run_test 170 "test lctl df to handle corrupted log ====================="
17884
17885 test_171() { # bug20592
17886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17887
17888         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17889         $LCTL set_param fail_loc=0x50e
17890         $LCTL set_param fail_val=3000
17891         multiop_bg_pause $DIR/$tfile O_s || true
17892         local MULTIPID=$!
17893         kill -USR1 $MULTIPID
17894         # cause log dump
17895         sleep 3
17896         wait $MULTIPID
17897         if dmesg | grep "recursive fault"; then
17898                 error "caught a recursive fault"
17899         fi
17900         $LCTL set_param fail_loc=0
17901         true
17902 }
17903 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17904
17905 test_172() {
17906
17907         #define OBD_FAIL_OBD_CLEANUP  0x60e
17908         $LCTL set_param fail_loc=0x60e
17909         umount $MOUNT || error "umount $MOUNT failed"
17910         stack_trap "mount_client $MOUNT"
17911
17912         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17913                 error "no client OBDs are remained"
17914
17915         $LCTL dl | while read devno state type name foo; do
17916                 case $type in
17917                 lov|osc|lmv|mdc)
17918                         $LCTL --device $name cleanup
17919                         $LCTL --device $name detach
17920                         ;;
17921                 *)
17922                         # skip server devices
17923                         ;;
17924                 esac
17925         done
17926
17927         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17928                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17929                 error "some client OBDs are still remained"
17930         fi
17931
17932 }
17933 run_test 172 "manual device removal with lctl cleanup/detach ======"
17934
17935 # it would be good to share it with obdfilter-survey/iokit-libecho code
17936 setup_obdecho_osc () {
17937         local rc=0
17938         local ost_nid=$1
17939         local obdfilter_name=$2
17940         echo "Creating new osc for $obdfilter_name on $ost_nid"
17941         # make sure we can find loopback nid
17942         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17943
17944         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17945                            ${obdfilter_name}_osc_UUID || rc=2; }
17946         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17947                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17948         return $rc
17949 }
17950
17951 cleanup_obdecho_osc () {
17952         local obdfilter_name=$1
17953         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17954         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17955         return 0
17956 }
17957
17958 obdecho_test() {
17959         local OBD=$1
17960         local node=$2
17961         local pages=${3:-64}
17962         local rc=0
17963         local id
17964
17965         local count=10
17966         local obd_size=$(get_obd_size $node $OBD)
17967         local page_size=$(get_page_size $node)
17968         if [[ -n "$obd_size" ]]; then
17969                 local new_count=$((obd_size / (pages * page_size / 1024)))
17970                 [[ $new_count -ge $count ]] || count=$new_count
17971         fi
17972
17973         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17974         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17975                            rc=2; }
17976         if [ $rc -eq 0 ]; then
17977             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17978             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17979         fi
17980         echo "New object id is $id"
17981         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17982                            rc=4; }
17983         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17984                            "test_brw $count w v $pages $id" || rc=4; }
17985         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17986                            rc=4; }
17987         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17988                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17989         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17990                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17991         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17992         return $rc
17993 }
17994
17995 test_180a() {
17996         skip "obdecho on osc is no longer supported"
17997 }
17998 run_test 180a "test obdecho on osc"
17999
18000 test_180b() {
18001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18002         remote_ost_nodsh && skip "remote OST with nodsh"
18003
18004         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18005                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18006                 error "failed to load module obdecho"
18007
18008         local target=$(do_facet ost1 $LCTL dl |
18009                        awk '/obdfilter/ { print $4; exit; }')
18010
18011         if [ -n "$target" ]; then
18012                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18013         else
18014                 do_facet ost1 $LCTL dl
18015                 error "there is no obdfilter target on ost1"
18016         fi
18017 }
18018 run_test 180b "test obdecho directly on obdfilter"
18019
18020 test_180c() { # LU-2598
18021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18022         remote_ost_nodsh && skip "remote OST with nodsh"
18023         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18024                 skip "Need MDS version at least 2.4.0"
18025
18026         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18027                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18028                 error "failed to load module obdecho"
18029
18030         local target=$(do_facet ost1 $LCTL dl |
18031                        awk '/obdfilter/ { print $4; exit; }')
18032
18033         if [ -n "$target" ]; then
18034                 local pages=16384 # 64MB bulk I/O RPC size
18035
18036                 obdecho_test "$target" ost1 "$pages" ||
18037                         error "obdecho_test with pages=$pages failed with $?"
18038         else
18039                 do_facet ost1 $LCTL dl
18040                 error "there is no obdfilter target on ost1"
18041         fi
18042 }
18043 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18044
18045 test_181() { # bug 22177
18046         test_mkdir $DIR/$tdir
18047         # create enough files to index the directory
18048         createmany -o $DIR/$tdir/foobar 4000
18049         # print attributes for debug purpose
18050         lsattr -d .
18051         # open dir
18052         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18053         MULTIPID=$!
18054         # remove the files & current working dir
18055         unlinkmany $DIR/$tdir/foobar 4000
18056         rmdir $DIR/$tdir
18057         kill -USR1 $MULTIPID
18058         wait $MULTIPID
18059         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18060         return 0
18061 }
18062 run_test 181 "Test open-unlinked dir ========================"
18063
18064 test_182a() {
18065         local fcount=1000
18066         local tcount=10
18067
18068         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18069
18070         $LCTL set_param mdc.*.rpc_stats=clear
18071
18072         for (( i = 0; i < $tcount; i++ )) ; do
18073                 mkdir $DIR/$tdir/$i
18074         done
18075
18076         for (( i = 0; i < $tcount; i++ )) ; do
18077                 createmany -o $DIR/$tdir/$i/f- $fcount &
18078         done
18079         wait
18080
18081         for (( i = 0; i < $tcount; i++ )) ; do
18082                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18083         done
18084         wait
18085
18086         $LCTL get_param mdc.*.rpc_stats
18087
18088         rm -rf $DIR/$tdir
18089 }
18090 run_test 182a "Test parallel modify metadata operations from mdc"
18091
18092 test_182b() {
18093         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18094         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18095         local dcount=1000
18096         local tcount=10
18097         local stime
18098         local etime
18099         local delta
18100
18101         do_facet mds1 $LCTL list_param \
18102                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18103                 skip "MDS lacks parallel RPC handling"
18104
18105         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18106
18107         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18108                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18109
18110         stime=$(date +%s)
18111         createmany -i 0 -d $DIR/$tdir/t- $tcount
18112
18113         for (( i = 0; i < $tcount; i++ )) ; do
18114                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18115         done
18116         wait
18117         etime=$(date +%s)
18118         delta=$((etime - stime))
18119         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18120
18121         stime=$(date +%s)
18122         for (( i = 0; i < $tcount; i++ )) ; do
18123                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18124         done
18125         wait
18126         etime=$(date +%s)
18127         delta=$((etime - stime))
18128         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18129
18130         rm -rf $DIR/$tdir
18131
18132         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18133
18134         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18135
18136         stime=$(date +%s)
18137         createmany -i 0 -d $DIR/$tdir/t- $tcount
18138
18139         for (( i = 0; i < $tcount; i++ )) ; do
18140                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18141         done
18142         wait
18143         etime=$(date +%s)
18144         delta=$((etime - stime))
18145         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18146
18147         stime=$(date +%s)
18148         for (( i = 0; i < $tcount; i++ )) ; do
18149                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18150         done
18151         wait
18152         etime=$(date +%s)
18153         delta=$((etime - stime))
18154         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18155
18156         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18157 }
18158 run_test 182b "Test parallel modify metadata operations from osp"
18159
18160 test_183() { # LU-2275
18161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18162         remote_mds_nodsh && skip "remote MDS with nodsh"
18163         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18164                 skip "Need MDS version at least 2.3.56"
18165
18166         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18167         echo aaa > $DIR/$tdir/$tfile
18168
18169 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18170         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18171
18172         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18173         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18174
18175         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18176
18177         # Flush negative dentry cache
18178         touch $DIR/$tdir/$tfile
18179
18180         # We are not checking for any leaked references here, they'll
18181         # become evident next time we do cleanup with module unload.
18182         rm -rf $DIR/$tdir
18183 }
18184 run_test 183 "No crash or request leak in case of strange dispositions ========"
18185
18186 # test suite 184 is for LU-2016, LU-2017
18187 test_184a() {
18188         check_swap_layouts_support
18189
18190         dir0=$DIR/$tdir/$testnum
18191         test_mkdir -p -c1 $dir0
18192         ref1=/etc/passwd
18193         ref2=/etc/group
18194         file1=$dir0/f1
18195         file2=$dir0/f2
18196         $LFS setstripe -c1 $file1
18197         cp $ref1 $file1
18198         $LFS setstripe -c2 $file2
18199         cp $ref2 $file2
18200         gen1=$($LFS getstripe -g $file1)
18201         gen2=$($LFS getstripe -g $file2)
18202
18203         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18204         gen=$($LFS getstripe -g $file1)
18205         [[ $gen1 != $gen ]] ||
18206                 error "Layout generation on $file1 does not change"
18207         gen=$($LFS getstripe -g $file2)
18208         [[ $gen2 != $gen ]] ||
18209                 error "Layout generation on $file2 does not change"
18210
18211         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18212         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18213
18214         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18215 }
18216 run_test 184a "Basic layout swap"
18217
18218 test_184b() {
18219         check_swap_layouts_support
18220
18221         dir0=$DIR/$tdir/$testnum
18222         mkdir -p $dir0 || error "creating dir $dir0"
18223         file1=$dir0/f1
18224         file2=$dir0/f2
18225         file3=$dir0/f3
18226         dir1=$dir0/d1
18227         dir2=$dir0/d2
18228         mkdir $dir1 $dir2
18229         $LFS setstripe -c1 $file1
18230         $LFS setstripe -c2 $file2
18231         $LFS setstripe -c1 $file3
18232         chown $RUNAS_ID $file3
18233         gen1=$($LFS getstripe -g $file1)
18234         gen2=$($LFS getstripe -g $file2)
18235
18236         $LFS swap_layouts $dir1 $dir2 &&
18237                 error "swap of directories layouts should fail"
18238         $LFS swap_layouts $dir1 $file1 &&
18239                 error "swap of directory and file layouts should fail"
18240         $RUNAS $LFS swap_layouts $file1 $file2 &&
18241                 error "swap of file we cannot write should fail"
18242         $LFS swap_layouts $file1 $file3 &&
18243                 error "swap of file with different owner should fail"
18244         /bin/true # to clear error code
18245 }
18246 run_test 184b "Forbidden layout swap (will generate errors)"
18247
18248 test_184c() {
18249         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18250         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18251         check_swap_layouts_support
18252         check_swap_layout_no_dom $DIR
18253
18254         local dir0=$DIR/$tdir/$testnum
18255         mkdir -p $dir0 || error "creating dir $dir0"
18256
18257         local ref1=$dir0/ref1
18258         local ref2=$dir0/ref2
18259         local file1=$dir0/file1
18260         local file2=$dir0/file2
18261         # create a file large enough for the concurrent test
18262         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18263         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18264         echo "ref file size: ref1($(stat -c %s $ref1))," \
18265              "ref2($(stat -c %s $ref2))"
18266
18267         cp $ref2 $file2
18268         dd if=$ref1 of=$file1 bs=16k &
18269         local DD_PID=$!
18270
18271         # Make sure dd starts to copy file, but wait at most 5 seconds
18272         local loops=0
18273         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18274
18275         $LFS swap_layouts $file1 $file2
18276         local rc=$?
18277         wait $DD_PID
18278         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18279         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18280
18281         # how many bytes copied before swapping layout
18282         local copied=$(stat -c %s $file2)
18283         local remaining=$(stat -c %s $ref1)
18284         remaining=$((remaining - copied))
18285         echo "Copied $copied bytes before swapping layout..."
18286
18287         cmp -n $copied $file1 $ref2 | grep differ &&
18288                 error "Content mismatch [0, $copied) of ref2 and file1"
18289         cmp -n $copied $file2 $ref1 ||
18290                 error "Content mismatch [0, $copied) of ref1 and file2"
18291         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18292                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18293
18294         # clean up
18295         rm -f $ref1 $ref2 $file1 $file2
18296 }
18297 run_test 184c "Concurrent write and layout swap"
18298
18299 test_184d() {
18300         check_swap_layouts_support
18301         check_swap_layout_no_dom $DIR
18302         [ -z "$(which getfattr 2>/dev/null)" ] &&
18303                 skip_env "no getfattr command"
18304
18305         local file1=$DIR/$tdir/$tfile-1
18306         local file2=$DIR/$tdir/$tfile-2
18307         local file3=$DIR/$tdir/$tfile-3
18308         local lovea1
18309         local lovea2
18310
18311         mkdir -p $DIR/$tdir
18312         touch $file1 || error "create $file1 failed"
18313         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18314                 error "create $file2 failed"
18315         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18316                 error "create $file3 failed"
18317         lovea1=$(get_layout_param $file1)
18318
18319         $LFS swap_layouts $file2 $file3 ||
18320                 error "swap $file2 $file3 layouts failed"
18321         $LFS swap_layouts $file1 $file2 ||
18322                 error "swap $file1 $file2 layouts failed"
18323
18324         lovea2=$(get_layout_param $file2)
18325         echo "$lovea1"
18326         echo "$lovea2"
18327         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18328
18329         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18330         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18331 }
18332 run_test 184d "allow stripeless layouts swap"
18333
18334 test_184e() {
18335         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18336                 skip "Need MDS version at least 2.6.94"
18337         check_swap_layouts_support
18338         check_swap_layout_no_dom $DIR
18339         [ -z "$(which getfattr 2>/dev/null)" ] &&
18340                 skip_env "no getfattr command"
18341
18342         local file1=$DIR/$tdir/$tfile-1
18343         local file2=$DIR/$tdir/$tfile-2
18344         local file3=$DIR/$tdir/$tfile-3
18345         local lovea
18346
18347         mkdir -p $DIR/$tdir
18348         touch $file1 || error "create $file1 failed"
18349         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18350                 error "create $file2 failed"
18351         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18352                 error "create $file3 failed"
18353
18354         $LFS swap_layouts $file1 $file2 ||
18355                 error "swap $file1 $file2 layouts failed"
18356
18357         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18358         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18359
18360         echo 123 > $file1 || error "Should be able to write into $file1"
18361
18362         $LFS swap_layouts $file1 $file3 ||
18363                 error "swap $file1 $file3 layouts failed"
18364
18365         echo 123 > $file1 || error "Should be able to write into $file1"
18366
18367         rm -rf $file1 $file2 $file3
18368 }
18369 run_test 184e "Recreate layout after stripeless layout swaps"
18370
18371 test_184f() {
18372         # Create a file with name longer than sizeof(struct stat) ==
18373         # 144 to see if we can get chars from the file name to appear
18374         # in the returned striping. Note that 'f' == 0x66.
18375         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18376
18377         mkdir -p $DIR/$tdir
18378         mcreate $DIR/$tdir/$file
18379         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18380                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18381         fi
18382 }
18383 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18384
18385 test_185() { # LU-2441
18386         # LU-3553 - no volatile file support in old servers
18387         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18388                 skip "Need MDS version at least 2.3.60"
18389
18390         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18391         touch $DIR/$tdir/spoo
18392         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18393         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18394                 error "cannot create/write a volatile file"
18395         [ "$FILESET" == "" ] &&
18396         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18397                 error "FID is still valid after close"
18398
18399         multiop_bg_pause $DIR/$tdir vVw4096_c
18400         local multi_pid=$!
18401
18402         local OLD_IFS=$IFS
18403         IFS=":"
18404         local fidv=($fid)
18405         IFS=$OLD_IFS
18406         # assume that the next FID for this client is sequential, since stdout
18407         # is unfortunately eaten by multiop_bg_pause
18408         local n=$((${fidv[1]} + 1))
18409         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18410         if [ "$FILESET" == "" ]; then
18411                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18412                         error "FID is missing before close"
18413         fi
18414         kill -USR1 $multi_pid
18415         # 1 second delay, so if mtime change we will see it
18416         sleep 1
18417         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18418         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18419 }
18420 run_test 185 "Volatile file support"
18421
18422 function create_check_volatile() {
18423         local idx=$1
18424         local tgt
18425
18426         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18427         local PID=$!
18428         sleep 1
18429         local FID=$(cat /tmp/${tfile}.fid)
18430         [ "$FID" == "" ] && error "can't get FID for volatile"
18431         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18432         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18433         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18434         kill -USR1 $PID
18435         wait
18436         sleep 1
18437         cancel_lru_locks mdc # flush opencache
18438         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18439         return 0
18440 }
18441
18442 test_185a(){
18443         # LU-12516 - volatile creation via .lustre
18444         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18445                 skip "Need MDS version at least 2.3.55"
18446
18447         create_check_volatile 0
18448         [ $MDSCOUNT -lt 2 ] && return 0
18449
18450         # DNE case
18451         create_check_volatile 1
18452
18453         return 0
18454 }
18455 run_test 185a "Volatile file creation in .lustre/fid/"
18456
18457 test_187a() {
18458         remote_mds_nodsh && skip "remote MDS with nodsh"
18459         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18460                 skip "Need MDS version at least 2.3.0"
18461
18462         local dir0=$DIR/$tdir/$testnum
18463         mkdir -p $dir0 || error "creating dir $dir0"
18464
18465         local file=$dir0/file1
18466         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18467         local dv1=$($LFS data_version $file)
18468         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18469         local dv2=$($LFS data_version $file)
18470         [[ $dv1 != $dv2 ]] ||
18471                 error "data version did not change on write $dv1 == $dv2"
18472
18473         # clean up
18474         rm -f $file1
18475 }
18476 run_test 187a "Test data version change"
18477
18478 test_187b() {
18479         remote_mds_nodsh && skip "remote MDS with nodsh"
18480         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18481                 skip "Need MDS version at least 2.3.0"
18482
18483         local dir0=$DIR/$tdir/$testnum
18484         mkdir -p $dir0 || error "creating dir $dir0"
18485
18486         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18487         [[ ${DV[0]} != ${DV[1]} ]] ||
18488                 error "data version did not change on write"\
18489                       " ${DV[0]} == ${DV[1]}"
18490
18491         # clean up
18492         rm -f $file1
18493 }
18494 run_test 187b "Test data version change on volatile file"
18495
18496 test_200() {
18497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18498         remote_mgs_nodsh && skip "remote MGS with nodsh"
18499         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18500
18501         local POOL=${POOL:-cea1}
18502         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18503         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18504         # Pool OST targets
18505         local first_ost=0
18506         local last_ost=$(($OSTCOUNT - 1))
18507         local ost_step=2
18508         local ost_list=$(seq $first_ost $ost_step $last_ost)
18509         local ost_range="$first_ost $last_ost $ost_step"
18510         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18511         local file_dir=$POOL_ROOT/file_tst
18512         local subdir=$test_path/subdir
18513         local rc=0
18514
18515         while : ; do
18516                 # former test_200a test_200b
18517                 pool_add $POOL                          || { rc=$? ; break; }
18518                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18519                 # former test_200c test_200d
18520                 mkdir -p $test_path
18521                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18522                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18523                 mkdir -p $subdir
18524                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18525                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18526                                                         || { rc=$? ; break; }
18527                 # former test_200e test_200f
18528                 local files=$((OSTCOUNT*3))
18529                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18530                                                         || { rc=$? ; break; }
18531                 pool_create_files $POOL $file_dir $files "$ost_list" \
18532                                                         || { rc=$? ; break; }
18533                 # former test_200g test_200h
18534                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18535                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18536
18537                 # former test_201a test_201b test_201c
18538                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18539
18540                 local f=$test_path/$tfile
18541                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18542                 pool_remove $POOL $f                    || { rc=$? ; break; }
18543                 break
18544         done
18545
18546         destroy_test_pools
18547
18548         return $rc
18549 }
18550 run_test 200 "OST pools"
18551
18552 # usage: default_attr <count | size | offset>
18553 default_attr() {
18554         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18555 }
18556
18557 # usage: check_default_stripe_attr
18558 check_default_stripe_attr() {
18559         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18560         case $1 in
18561         --stripe-count|-c)
18562                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18563         --stripe-size|-S)
18564                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18565         --stripe-index|-i)
18566                 EXPECTED=-1;;
18567         *)
18568                 error "unknown getstripe attr '$1'"
18569         esac
18570
18571         [ $ACTUAL == $EXPECTED ] ||
18572                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18573 }
18574
18575 test_204a() {
18576         test_mkdir $DIR/$tdir
18577         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18578
18579         check_default_stripe_attr --stripe-count
18580         check_default_stripe_attr --stripe-size
18581         check_default_stripe_attr --stripe-index
18582 }
18583 run_test 204a "Print default stripe attributes"
18584
18585 test_204b() {
18586         test_mkdir $DIR/$tdir
18587         $LFS setstripe --stripe-count 1 $DIR/$tdir
18588
18589         check_default_stripe_attr --stripe-size
18590         check_default_stripe_attr --stripe-index
18591 }
18592 run_test 204b "Print default stripe size and offset"
18593
18594 test_204c() {
18595         test_mkdir $DIR/$tdir
18596         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18597
18598         check_default_stripe_attr --stripe-count
18599         check_default_stripe_attr --stripe-index
18600 }
18601 run_test 204c "Print default stripe count and offset"
18602
18603 test_204d() {
18604         test_mkdir $DIR/$tdir
18605         $LFS setstripe --stripe-index 0 $DIR/$tdir
18606
18607         check_default_stripe_attr --stripe-count
18608         check_default_stripe_attr --stripe-size
18609 }
18610 run_test 204d "Print default stripe count and size"
18611
18612 test_204e() {
18613         test_mkdir $DIR/$tdir
18614         $LFS setstripe -d $DIR/$tdir
18615
18616         check_default_stripe_attr --stripe-count --raw
18617         check_default_stripe_attr --stripe-size --raw
18618         check_default_stripe_attr --stripe-index --raw
18619 }
18620 run_test 204e "Print raw stripe attributes"
18621
18622 test_204f() {
18623         test_mkdir $DIR/$tdir
18624         $LFS setstripe --stripe-count 1 $DIR/$tdir
18625
18626         check_default_stripe_attr --stripe-size --raw
18627         check_default_stripe_attr --stripe-index --raw
18628 }
18629 run_test 204f "Print raw stripe size and offset"
18630
18631 test_204g() {
18632         test_mkdir $DIR/$tdir
18633         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18634
18635         check_default_stripe_attr --stripe-count --raw
18636         check_default_stripe_attr --stripe-index --raw
18637 }
18638 run_test 204g "Print raw stripe count and offset"
18639
18640 test_204h() {
18641         test_mkdir $DIR/$tdir
18642         $LFS setstripe --stripe-index 0 $DIR/$tdir
18643
18644         check_default_stripe_attr --stripe-count --raw
18645         check_default_stripe_attr --stripe-size --raw
18646 }
18647 run_test 204h "Print raw stripe count and size"
18648
18649 # Figure out which job scheduler is being used, if any,
18650 # or use a fake one
18651 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18652         JOBENV=SLURM_JOB_ID
18653 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18654         JOBENV=LSB_JOBID
18655 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18656         JOBENV=PBS_JOBID
18657 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18658         JOBENV=LOADL_STEP_ID
18659 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18660         JOBENV=JOB_ID
18661 else
18662         $LCTL list_param jobid_name > /dev/null 2>&1
18663         if [ $? -eq 0 ]; then
18664                 JOBENV=nodelocal
18665         else
18666                 JOBENV=FAKE_JOBID
18667         fi
18668 fi
18669 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18670
18671 verify_jobstats() {
18672         local cmd=($1)
18673         shift
18674         local facets="$@"
18675
18676 # we don't really need to clear the stats for this test to work, since each
18677 # command has a unique jobid, but it makes debugging easier if needed.
18678 #       for facet in $facets; do
18679 #               local dev=$(convert_facet2label $facet)
18680 #               # clear old jobstats
18681 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18682 #       done
18683
18684         # use a new JobID for each test, or we might see an old one
18685         [ "$JOBENV" = "FAKE_JOBID" ] &&
18686                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18687
18688         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18689
18690         [ "$JOBENV" = "nodelocal" ] && {
18691                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18692                 $LCTL set_param jobid_name=$FAKE_JOBID
18693                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18694         }
18695
18696         log "Test: ${cmd[*]}"
18697         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18698
18699         if [ $JOBENV = "FAKE_JOBID" ]; then
18700                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18701         else
18702                 ${cmd[*]}
18703         fi
18704
18705         # all files are created on OST0000
18706         for facet in $facets; do
18707                 local stats="*.$(convert_facet2label $facet).job_stats"
18708
18709                 # strip out libtool wrappers for in-tree executables
18710                 if (( $(do_facet $facet lctl get_param $stats |
18711                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18712                         do_facet $facet lctl get_param $stats
18713                         error "No jobstats for $JOBVAL found on $facet::$stats"
18714                 fi
18715         done
18716 }
18717
18718 jobstats_set() {
18719         local new_jobenv=$1
18720
18721         set_persistent_param_and_check client "jobid_var" \
18722                 "$FSNAME.sys.jobid_var" $new_jobenv
18723 }
18724
18725 test_205a() { # Job stats
18726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18727         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18728                 skip "Need MDS version with at least 2.7.1"
18729         remote_mgs_nodsh && skip "remote MGS with nodsh"
18730         remote_mds_nodsh && skip "remote MDS with nodsh"
18731         remote_ost_nodsh && skip "remote OST with nodsh"
18732         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18733                 skip "Server doesn't support jobstats"
18734         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18735
18736         local old_jobenv=$($LCTL get_param -n jobid_var)
18737         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18738
18739         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18740                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18741         else
18742                 stack_trap "do_facet mgs $PERM_CMD \
18743                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18744         fi
18745         changelog_register
18746
18747         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18748                                 mdt.*.job_cleanup_interval | head -n 1)
18749         local new_interval=5
18750         do_facet $SINGLEMDS \
18751                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18752         stack_trap "do_facet $SINGLEMDS \
18753                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18754         local start=$SECONDS
18755
18756         local cmd
18757         # mkdir
18758         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18759         verify_jobstats "$cmd" "$SINGLEMDS"
18760         # rmdir
18761         cmd="rmdir $DIR/$tdir"
18762         verify_jobstats "$cmd" "$SINGLEMDS"
18763         # mkdir on secondary MDT
18764         if [ $MDSCOUNT -gt 1 ]; then
18765                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18766                 verify_jobstats "$cmd" "mds2"
18767         fi
18768         # mknod
18769         cmd="mknod $DIR/$tfile c 1 3"
18770         verify_jobstats "$cmd" "$SINGLEMDS"
18771         # unlink
18772         cmd="rm -f $DIR/$tfile"
18773         verify_jobstats "$cmd" "$SINGLEMDS"
18774         # create all files on OST0000 so verify_jobstats can find OST stats
18775         # open & close
18776         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18777         verify_jobstats "$cmd" "$SINGLEMDS"
18778         # setattr
18779         cmd="touch $DIR/$tfile"
18780         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18781         # write
18782         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18783         verify_jobstats "$cmd" "ost1"
18784         # read
18785         cancel_lru_locks osc
18786         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18787         verify_jobstats "$cmd" "ost1"
18788         # truncate
18789         cmd="$TRUNCATE $DIR/$tfile 0"
18790         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18791         # rename
18792         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18793         verify_jobstats "$cmd" "$SINGLEMDS"
18794         # jobstats expiry - sleep until old stats should be expired
18795         local left=$((new_interval + 5 - (SECONDS - start)))
18796         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18797                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18798                         "0" $left
18799         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18800         verify_jobstats "$cmd" "$SINGLEMDS"
18801         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18802             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18803
18804         # Ensure that jobid are present in changelog (if supported by MDS)
18805         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18806                 changelog_dump | tail -10
18807                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18808                 [ $jobids -eq 9 ] ||
18809                         error "Wrong changelog jobid count $jobids != 9"
18810
18811                 # LU-5862
18812                 JOBENV="disable"
18813                 jobstats_set $JOBENV
18814                 touch $DIR/$tfile
18815                 changelog_dump | grep $tfile
18816                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18817                 [ $jobids -eq 0 ] ||
18818                         error "Unexpected jobids when jobid_var=$JOBENV"
18819         fi
18820
18821         # test '%j' access to environment variable - if supported
18822         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18823                 JOBENV="JOBCOMPLEX"
18824                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18825
18826                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18827         fi
18828
18829         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18830                 JOBENV="JOBCOMPLEX"
18831                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18832
18833                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18834         fi
18835
18836         # test '%j' access to per-session jobid - if supported
18837         if lctl list_param jobid_this_session > /dev/null 2>&1
18838         then
18839                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18840                 lctl set_param jobid_this_session=$USER
18841
18842                 JOBENV="JOBCOMPLEX"
18843                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18844
18845                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18846         fi
18847 }
18848 run_test 205a "Verify job stats"
18849
18850 # LU-13117, LU-13597
18851 test_205b() {
18852         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18853                 skip "Need MDS version at least 2.13.54.91"
18854
18855         local job_stats="mdt.*.job_stats"
18856         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18857
18858         do_facet mds1 $LCTL set_param $job_stats=clear
18859
18860         # Setting jobid_var to USER might not be supported
18861         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18862         $LCTL set_param jobid_var=USER || true
18863         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18864         $LCTL set_param jobid_name="%j.%e.%u"
18865
18866         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18867         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18868                 { do_facet mds1 $LCTL get_param $job_stats;
18869                   error "Unexpected jobid found"; }
18870         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18871                 { do_facet mds1 $LCTL get_param $job_stats;
18872                   error "wrong job_stats format found"; }
18873
18874         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18875                 echo "MDS does not yet escape jobid" && return 0
18876         $LCTL set_param jobid_var=TEST205b
18877         env -i TEST205b="has sp" touch $DIR/$tfile.2
18878         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18879                 { do_facet mds1 $LCTL get_param $job_stats;
18880                   error "jobid not escaped"; }
18881 }
18882 run_test 205b "Verify job stats jobid and output format"
18883
18884 # LU-13733
18885 test_205c() {
18886         $LCTL set_param llite.*.stats=0
18887         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18888         $LCTL get_param llite.*.stats
18889         $LCTL get_param llite.*.stats | grep \
18890                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18891                         error "wrong client stats format found"
18892 }
18893 run_test 205c "Verify client stats format"
18894
18895 # LU-1480, LU-1773 and LU-1657
18896 test_206() {
18897         mkdir -p $DIR/$tdir
18898         $LFS setstripe -c -1 $DIR/$tdir
18899 #define OBD_FAIL_LOV_INIT 0x1403
18900         $LCTL set_param fail_loc=0xa0001403
18901         $LCTL set_param fail_val=1
18902         touch $DIR/$tdir/$tfile || true
18903 }
18904 run_test 206 "fail lov_init_raid0() doesn't lbug"
18905
18906 test_207a() {
18907         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18908         local fsz=`stat -c %s $DIR/$tfile`
18909         cancel_lru_locks mdc
18910
18911         # do not return layout in getattr intent
18912 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18913         $LCTL set_param fail_loc=0x170
18914         local sz=`stat -c %s $DIR/$tfile`
18915
18916         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18917
18918         rm -rf $DIR/$tfile
18919 }
18920 run_test 207a "can refresh layout at glimpse"
18921
18922 test_207b() {
18923         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18924         local cksum=`md5sum $DIR/$tfile`
18925         local fsz=`stat -c %s $DIR/$tfile`
18926         cancel_lru_locks mdc
18927         cancel_lru_locks osc
18928
18929         # do not return layout in getattr intent
18930 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18931         $LCTL set_param fail_loc=0x171
18932
18933         # it will refresh layout after the file is opened but before read issues
18934         echo checksum is "$cksum"
18935         echo "$cksum" |md5sum -c --quiet || error "file differs"
18936
18937         rm -rf $DIR/$tfile
18938 }
18939 run_test 207b "can refresh layout at open"
18940
18941 test_208() {
18942         # FIXME: in this test suite, only RD lease is used. This is okay
18943         # for now as only exclusive open is supported. After generic lease
18944         # is done, this test suite should be revised. - Jinshan
18945
18946         remote_mds_nodsh && skip "remote MDS with nodsh"
18947         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18948                 skip "Need MDS version at least 2.4.52"
18949
18950         echo "==== test 1: verify get lease work"
18951         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18952
18953         echo "==== test 2: verify lease can be broken by upcoming open"
18954         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18955         local PID=$!
18956         sleep 2
18957
18958         $MULTIOP $DIR/$tfile oO_RDWR:c
18959         kill -USR1 $PID && wait $PID || error "break lease error"
18960
18961         echo "==== test 3: verify lease can't be granted if an open already exists"
18962         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18963         local PID=$!
18964         sleep 2
18965
18966         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18967         kill -USR1 $PID && wait $PID || error "open file error"
18968
18969         echo "==== test 4: lease can sustain over recovery"
18970         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18971         PID=$!
18972         sleep 2
18973
18974         fail mds1
18975
18976         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18977
18978         echo "==== test 5: lease broken can't be regained by replay"
18979         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18980         PID=$!
18981         sleep 2
18982
18983         # open file to break lease and then recovery
18984         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18985         fail mds1
18986
18987         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18988
18989         rm -f $DIR/$tfile
18990 }
18991 run_test 208 "Exclusive open"
18992
18993 test_209() {
18994         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18995                 skip_env "must have disp_stripe"
18996
18997         touch $DIR/$tfile
18998         sync; sleep 5; sync;
18999
19000         echo 3 > /proc/sys/vm/drop_caches
19001         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19002                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19003         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19004
19005         # open/close 500 times
19006         for i in $(seq 500); do
19007                 cat $DIR/$tfile
19008         done
19009
19010         echo 3 > /proc/sys/vm/drop_caches
19011         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19012                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19013         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19014
19015         echo "before: $req_before, after: $req_after"
19016         [ $((req_after - req_before)) -ge 300 ] &&
19017                 error "open/close requests are not freed"
19018         return 0
19019 }
19020 run_test 209 "read-only open/close requests should be freed promptly"
19021
19022 test_210() {
19023         local pid
19024
19025         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19026         pid=$!
19027         sleep 1
19028
19029         $LFS getstripe $DIR/$tfile
19030         kill -USR1 $pid
19031         wait $pid || error "multiop failed"
19032
19033         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19034         pid=$!
19035         sleep 1
19036
19037         $LFS getstripe $DIR/$tfile
19038         kill -USR1 $pid
19039         wait $pid || error "multiop failed"
19040 }
19041 run_test 210 "lfs getstripe does not break leases"
19042
19043 test_212() {
19044         size=`date +%s`
19045         size=$((size % 8192 + 1))
19046         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19047         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19048         rm -f $DIR/f212 $DIR/f212.xyz
19049 }
19050 run_test 212 "Sendfile test ============================================"
19051
19052 test_213() {
19053         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19054         cancel_lru_locks osc
19055         lctl set_param fail_loc=0x8000040f
19056         # generate a read lock
19057         cat $DIR/$tfile > /dev/null
19058         # write to the file, it will try to cancel the above read lock.
19059         cat /etc/hosts >> $DIR/$tfile
19060 }
19061 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19062
19063 test_214() { # for bug 20133
19064         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19065         for (( i=0; i < 340; i++ )) ; do
19066                 touch $DIR/$tdir/d214c/a$i
19067         done
19068
19069         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19070         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19071         ls $DIR/d214c || error "ls $DIR/d214c failed"
19072         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19073         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19074 }
19075 run_test 214 "hash-indexed directory test - bug 20133"
19076
19077 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19078 create_lnet_proc_files() {
19079         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19080 }
19081
19082 # counterpart of create_lnet_proc_files
19083 remove_lnet_proc_files() {
19084         rm -f $TMP/lnet_$1.sys
19085 }
19086
19087 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19088 # 3rd arg as regexp for body
19089 check_lnet_proc_stats() {
19090         local l=$(cat "$TMP/lnet_$1" |wc -l)
19091         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19092
19093         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19094 }
19095
19096 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19097 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19098 # optional and can be regexp for 2nd line (lnet.routes case)
19099 check_lnet_proc_entry() {
19100         local blp=2          # blp stands for 'position of 1st line of body'
19101         [ -z "$5" ] || blp=3 # lnet.routes case
19102
19103         local l=$(cat "$TMP/lnet_$1" |wc -l)
19104         # subtracting one from $blp because the body can be empty
19105         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19106
19107         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19108                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19109
19110         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19111                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19112
19113         # bail out if any unexpected line happened
19114         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19115         [ "$?" != 0 ] || error "$2 misformatted"
19116 }
19117
19118 test_215() { # for bugs 18102, 21079, 21517
19119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19120
19121         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19122         local P='[1-9][0-9]*'           # positive numeric
19123         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19124         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19125         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19126         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19127
19128         local L1 # regexp for 1st line
19129         local L2 # regexp for 2nd line (optional)
19130         local BR # regexp for the rest (body)
19131
19132         # lnet.stats should look as 11 space-separated non-negative numerics
19133         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19134         create_lnet_proc_files "stats"
19135         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19136         remove_lnet_proc_files "stats"
19137
19138         # lnet.routes should look like this:
19139         # Routing disabled/enabled
19140         # net hops priority state router
19141         # where net is a string like tcp0, hops > 0, priority >= 0,
19142         # state is up/down,
19143         # router is a string like 192.168.1.1@tcp2
19144         L1="^Routing (disabled|enabled)$"
19145         L2="^net +hops +priority +state +router$"
19146         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19147         create_lnet_proc_files "routes"
19148         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19149         remove_lnet_proc_files "routes"
19150
19151         # lnet.routers should look like this:
19152         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19153         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19154         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19155         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19156         L1="^ref +rtr_ref +alive +router$"
19157         BR="^$P +$P +(up|down) +$NID$"
19158         create_lnet_proc_files "routers"
19159         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19160         remove_lnet_proc_files "routers"
19161
19162         # lnet.peers should look like this:
19163         # nid refs state last max rtr min tx min queue
19164         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19165         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19166         # numeric (0 or >0 or <0), queue >= 0.
19167         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19168         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19169         create_lnet_proc_files "peers"
19170         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19171         remove_lnet_proc_files "peers"
19172
19173         # lnet.buffers  should look like this:
19174         # pages count credits min
19175         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19176         L1="^pages +count +credits +min$"
19177         BR="^ +$N +$N +$I +$I$"
19178         create_lnet_proc_files "buffers"
19179         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19180         remove_lnet_proc_files "buffers"
19181
19182         # lnet.nis should look like this:
19183         # nid status alive refs peer rtr max tx min
19184         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19185         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19186         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19187         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19188         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19189         create_lnet_proc_files "nis"
19190         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19191         remove_lnet_proc_files "nis"
19192
19193         # can we successfully write to lnet.stats?
19194         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19195 }
19196 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19197
19198 test_216() { # bug 20317
19199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19200         remote_ost_nodsh && skip "remote OST with nodsh"
19201
19202         local node
19203         local facets=$(get_facets OST)
19204         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19205
19206         save_lustre_params client "osc.*.contention_seconds" > $p
19207         save_lustre_params $facets \
19208                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19209         save_lustre_params $facets \
19210                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19211         save_lustre_params $facets \
19212                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19213         clear_stats osc.*.osc_stats
19214
19215         # agressive lockless i/o settings
19216         do_nodes $(comma_list $(osts_nodes)) \
19217                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19218                         ldlm.namespaces.filter-*.contended_locks=0 \
19219                         ldlm.namespaces.filter-*.contention_seconds=60"
19220         lctl set_param -n osc.*.contention_seconds=60
19221
19222         $DIRECTIO write $DIR/$tfile 0 10 4096
19223         $CHECKSTAT -s 40960 $DIR/$tfile
19224
19225         # disable lockless i/o
19226         do_nodes $(comma_list $(osts_nodes)) \
19227                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19228                         ldlm.namespaces.filter-*.contended_locks=32 \
19229                         ldlm.namespaces.filter-*.contention_seconds=0"
19230         lctl set_param -n osc.*.contention_seconds=0
19231         clear_stats osc.*.osc_stats
19232
19233         dd if=/dev/zero of=$DIR/$tfile count=0
19234         $CHECKSTAT -s 0 $DIR/$tfile
19235
19236         restore_lustre_params <$p
19237         rm -f $p
19238         rm $DIR/$tfile
19239 }
19240 run_test 216 "check lockless direct write updates file size and kms correctly"
19241
19242 test_217() { # bug 22430
19243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19244
19245         local node
19246         local nid
19247
19248         for node in $(nodes_list); do
19249                 nid=$(host_nids_address $node $NETTYPE)
19250                 if [[ $nid = *-* ]] ; then
19251                         echo "lctl ping $(h2nettype $nid)"
19252                         lctl ping $(h2nettype $nid)
19253                 else
19254                         echo "skipping $node (no hyphen detected)"
19255                 fi
19256         done
19257 }
19258 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19259
19260 test_218() {
19261        # do directio so as not to populate the page cache
19262        log "creating a 10 Mb file"
19263        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19264        log "starting reads"
19265        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19266        log "truncating the file"
19267        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19268        log "killing dd"
19269        kill %+ || true # reads might have finished
19270        echo "wait until dd is finished"
19271        wait
19272        log "removing the temporary file"
19273        rm -rf $DIR/$tfile || error "tmp file removal failed"
19274 }
19275 run_test 218 "parallel read and truncate should not deadlock"
19276
19277 test_219() {
19278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19279
19280         # write one partial page
19281         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19282         # set no grant so vvp_io_commit_write will do sync write
19283         $LCTL set_param fail_loc=0x411
19284         # write a full page at the end of file
19285         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19286
19287         $LCTL set_param fail_loc=0
19288         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19289         $LCTL set_param fail_loc=0x411
19290         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19291
19292         # LU-4201
19293         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19294         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19295 }
19296 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19297
19298 test_220() { #LU-325
19299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19300         remote_ost_nodsh && skip "remote OST with nodsh"
19301         remote_mds_nodsh && skip "remote MDS with nodsh"
19302         remote_mgs_nodsh && skip "remote MGS with nodsh"
19303
19304         local OSTIDX=0
19305
19306         # create on MDT0000 so the last_id and next_id are correct
19307         mkdir_on_mdt0 $DIR/$tdir
19308         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19309         OST=${OST%_UUID}
19310
19311         # on the mdt's osc
19312         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19313         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19314                         osp.$mdtosc_proc1.prealloc_last_id)
19315         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19316                         osp.$mdtosc_proc1.prealloc_next_id)
19317
19318         $LFS df -i
19319
19320         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19321         #define OBD_FAIL_OST_ENOINO              0x229
19322         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19323         create_pool $FSNAME.$TESTNAME || return 1
19324         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19325
19326         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19327
19328         MDSOBJS=$((last_id - next_id))
19329         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19330
19331         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19332         echo "OST still has $count kbytes free"
19333
19334         echo "create $MDSOBJS files @next_id..."
19335         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19336
19337         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19338                         osp.$mdtosc_proc1.prealloc_last_id)
19339         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19340                         osp.$mdtosc_proc1.prealloc_next_id)
19341
19342         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19343         $LFS df -i
19344
19345         echo "cleanup..."
19346
19347         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19348         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19349
19350         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19351                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19352         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19353                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19354         echo "unlink $MDSOBJS files @$next_id..."
19355         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19356 }
19357 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19358
19359 test_221() {
19360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19361
19362         dd if=`which date` of=$MOUNT/date oflag=sync
19363         chmod +x $MOUNT/date
19364
19365         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19366         $LCTL set_param fail_loc=0x80001401
19367
19368         $MOUNT/date > /dev/null
19369         rm -f $MOUNT/date
19370 }
19371 run_test 221 "make sure fault and truncate race to not cause OOM"
19372
19373 test_222a () {
19374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19375
19376         rm -rf $DIR/$tdir
19377         test_mkdir $DIR/$tdir
19378         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19379         createmany -o $DIR/$tdir/$tfile 10
19380         cancel_lru_locks mdc
19381         cancel_lru_locks osc
19382         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19383         $LCTL set_param fail_loc=0x31a
19384         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19385         $LCTL set_param fail_loc=0
19386         rm -r $DIR/$tdir
19387 }
19388 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19389
19390 test_222b () {
19391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19392
19393         rm -rf $DIR/$tdir
19394         test_mkdir $DIR/$tdir
19395         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19396         createmany -o $DIR/$tdir/$tfile 10
19397         cancel_lru_locks mdc
19398         cancel_lru_locks osc
19399         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19400         $LCTL set_param fail_loc=0x31a
19401         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19402         $LCTL set_param fail_loc=0
19403 }
19404 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19405
19406 test_223 () {
19407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19408
19409         rm -rf $DIR/$tdir
19410         test_mkdir $DIR/$tdir
19411         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19412         createmany -o $DIR/$tdir/$tfile 10
19413         cancel_lru_locks mdc
19414         cancel_lru_locks osc
19415         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19416         $LCTL set_param fail_loc=0x31b
19417         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19418         $LCTL set_param fail_loc=0
19419         rm -r $DIR/$tdir
19420 }
19421 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19422
19423 test_224a() { # LU-1039, MRP-303
19424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19425         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19426         $LCTL set_param fail_loc=0x508
19427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19428         $LCTL set_param fail_loc=0
19429         df $DIR
19430 }
19431 run_test 224a "Don't panic on bulk IO failure"
19432
19433 test_224bd_sub() { # LU-1039, MRP-303
19434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19435         local timeout=$1
19436
19437         shift
19438         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19439
19440         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19441
19442         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19443         cancel_lru_locks osc
19444         set_checksums 0
19445         stack_trap "set_checksums $ORIG_CSUM" EXIT
19446         local at_max_saved=0
19447
19448         # adaptive timeouts may prevent seeing the issue
19449         if at_is_enabled; then
19450                 at_max_saved=$(at_max_get mds)
19451                 at_max_set 0 mds client
19452                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19453         fi
19454
19455         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19456         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19457         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19458
19459         do_facet ost1 $LCTL set_param fail_loc=0
19460         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19461         df $DIR
19462 }
19463
19464 test_224b() {
19465         test_224bd_sub 3 error "dd failed"
19466 }
19467 run_test 224b "Don't panic on bulk IO failure"
19468
19469 test_224c() { # LU-6441
19470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19471         remote_mds_nodsh && skip "remote MDS with nodsh"
19472
19473         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19474         save_writethrough $p
19475         set_cache writethrough on
19476
19477         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19478         local at_max=$($LCTL get_param -n at_max)
19479         local timeout=$($LCTL get_param -n timeout)
19480         local test_at="at_max"
19481         local param_at="$FSNAME.sys.at_max"
19482         local test_timeout="timeout"
19483         local param_timeout="$FSNAME.sys.timeout"
19484
19485         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19486
19487         set_persistent_param_and_check client "$test_at" "$param_at" 0
19488         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19489
19490         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19491         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19492         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19493         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19494         sync
19495         do_facet ost1 "$LCTL set_param fail_loc=0"
19496
19497         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19498         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19499                 $timeout
19500
19501         $LCTL set_param -n $pages_per_rpc
19502         restore_lustre_params < $p
19503         rm -f $p
19504 }
19505 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19506
19507 test_224d() { # LU-11169
19508         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19509 }
19510 run_test 224d "Don't corrupt data on bulk IO timeout"
19511
19512 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19513 test_225a () {
19514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19515         if [ -z ${MDSSURVEY} ]; then
19516                 skip_env "mds-survey not found"
19517         fi
19518         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19519                 skip "Need MDS version at least 2.2.51"
19520
19521         local mds=$(facet_host $SINGLEMDS)
19522         local target=$(do_nodes $mds 'lctl dl' |
19523                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19524
19525         local cmd1="file_count=1000 thrhi=4"
19526         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19527         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19528         local cmd="$cmd1 $cmd2 $cmd3"
19529
19530         rm -f ${TMP}/mds_survey*
19531         echo + $cmd
19532         eval $cmd || error "mds-survey with zero-stripe failed"
19533         cat ${TMP}/mds_survey*
19534         rm -f ${TMP}/mds_survey*
19535 }
19536 run_test 225a "Metadata survey sanity with zero-stripe"
19537
19538 test_225b () {
19539         if [ -z ${MDSSURVEY} ]; then
19540                 skip_env "mds-survey not found"
19541         fi
19542         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19543                 skip "Need MDS version at least 2.2.51"
19544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19545         remote_mds_nodsh && skip "remote MDS with nodsh"
19546         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19547                 skip_env "Need to mount OST to test"
19548         fi
19549
19550         local mds=$(facet_host $SINGLEMDS)
19551         local target=$(do_nodes $mds 'lctl dl' |
19552                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19553
19554         local cmd1="file_count=1000 thrhi=4"
19555         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19556         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19557         local cmd="$cmd1 $cmd2 $cmd3"
19558
19559         rm -f ${TMP}/mds_survey*
19560         echo + $cmd
19561         eval $cmd || error "mds-survey with stripe_count failed"
19562         cat ${TMP}/mds_survey*
19563         rm -f ${TMP}/mds_survey*
19564 }
19565 run_test 225b "Metadata survey sanity with stripe_count = 1"
19566
19567 mcreate_path2fid () {
19568         local mode=$1
19569         local major=$2
19570         local minor=$3
19571         local name=$4
19572         local desc=$5
19573         local path=$DIR/$tdir/$name
19574         local fid
19575         local rc
19576         local fid_path
19577
19578         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19579                 error "cannot create $desc"
19580
19581         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19582         rc=$?
19583         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19584
19585         fid_path=$($LFS fid2path $MOUNT $fid)
19586         rc=$?
19587         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19588
19589         [ "$path" == "$fid_path" ] ||
19590                 error "fid2path returned $fid_path, expected $path"
19591
19592         echo "pass with $path and $fid"
19593 }
19594
19595 test_226a () {
19596         rm -rf $DIR/$tdir
19597         mkdir -p $DIR/$tdir
19598
19599         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19600         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19601         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19602         mcreate_path2fid 0040666 0 0 dir "directory"
19603         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19604         mcreate_path2fid 0100666 0 0 file "regular file"
19605         mcreate_path2fid 0120666 0 0 link "symbolic link"
19606         mcreate_path2fid 0140666 0 0 sock "socket"
19607 }
19608 run_test 226a "call path2fid and fid2path on files of all type"
19609
19610 test_226b () {
19611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19612
19613         local MDTIDX=1
19614
19615         rm -rf $DIR/$tdir
19616         mkdir -p $DIR/$tdir
19617         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19618                 error "create remote directory failed"
19619         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19620         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19621                                 "character special file (null)"
19622         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19623                                 "character special file (no device)"
19624         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19625         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19626                                 "block special file (loop)"
19627         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19628         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19629         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19630 }
19631 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19632
19633 test_226c () {
19634         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19635         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19636                 skip "Need MDS version at least 2.13.55"
19637
19638         local submnt=/mnt/submnt
19639         local srcfile=/etc/passwd
19640         local dstfile=$submnt/passwd
19641         local path
19642         local fid
19643
19644         rm -rf $DIR/$tdir
19645         rm -rf $submnt
19646         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19647                 error "create remote directory failed"
19648         mkdir -p $submnt || error "create $submnt failed"
19649         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19650                 error "mount $submnt failed"
19651         stack_trap "umount $submnt" EXIT
19652
19653         cp $srcfile $dstfile
19654         fid=$($LFS path2fid $dstfile)
19655         path=$($LFS fid2path $submnt "$fid")
19656         [ "$path" = "$dstfile" ] ||
19657                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19658 }
19659 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19660
19661 # LU-1299 Executing or running ldd on a truncated executable does not
19662 # cause an out-of-memory condition.
19663 test_227() {
19664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19665         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19666
19667         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19668         chmod +x $MOUNT/date
19669
19670         $MOUNT/date > /dev/null
19671         ldd $MOUNT/date > /dev/null
19672         rm -f $MOUNT/date
19673 }
19674 run_test 227 "running truncated executable does not cause OOM"
19675
19676 # LU-1512 try to reuse idle OI blocks
19677 test_228a() {
19678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19679         remote_mds_nodsh && skip "remote MDS with nodsh"
19680         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19681
19682         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19683         local myDIR=$DIR/$tdir
19684
19685         mkdir -p $myDIR
19686         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19687         $LCTL set_param fail_loc=0x80001002
19688         createmany -o $myDIR/t- 10000
19689         $LCTL set_param fail_loc=0
19690         # The guard is current the largest FID holder
19691         touch $myDIR/guard
19692         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19693                     tr -d '[')
19694         local IDX=$(($SEQ % 64))
19695
19696         do_facet $SINGLEMDS sync
19697         # Make sure journal flushed.
19698         sleep 6
19699         local blk1=$(do_facet $SINGLEMDS \
19700                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19701                      grep Blockcount | awk '{print $4}')
19702
19703         # Remove old files, some OI blocks will become idle.
19704         unlinkmany $myDIR/t- 10000
19705         # Create new files, idle OI blocks should be reused.
19706         createmany -o $myDIR/t- 2000
19707         do_facet $SINGLEMDS sync
19708         # Make sure journal flushed.
19709         sleep 6
19710         local blk2=$(do_facet $SINGLEMDS \
19711                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19712                      grep Blockcount | awk '{print $4}')
19713
19714         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19715 }
19716 run_test 228a "try to reuse idle OI blocks"
19717
19718 test_228b() {
19719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19720         remote_mds_nodsh && skip "remote MDS with nodsh"
19721         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19722
19723         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19724         local myDIR=$DIR/$tdir
19725
19726         mkdir -p $myDIR
19727         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19728         $LCTL set_param fail_loc=0x80001002
19729         createmany -o $myDIR/t- 10000
19730         $LCTL set_param fail_loc=0
19731         # The guard is current the largest FID holder
19732         touch $myDIR/guard
19733         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19734                     tr -d '[')
19735         local IDX=$(($SEQ % 64))
19736
19737         do_facet $SINGLEMDS sync
19738         # Make sure journal flushed.
19739         sleep 6
19740         local blk1=$(do_facet $SINGLEMDS \
19741                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19742                      grep Blockcount | awk '{print $4}')
19743
19744         # Remove old files, some OI blocks will become idle.
19745         unlinkmany $myDIR/t- 10000
19746
19747         # stop the MDT
19748         stop $SINGLEMDS || error "Fail to stop MDT."
19749         # remount the MDT
19750         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19751                 error "Fail to start MDT."
19752
19753         df $MOUNT || error "Fail to df."
19754         # Create new files, idle OI blocks should be reused.
19755         createmany -o $myDIR/t- 2000
19756         do_facet $SINGLEMDS sync
19757         # Make sure journal flushed.
19758         sleep 6
19759         local blk2=$(do_facet $SINGLEMDS \
19760                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19761                      grep Blockcount | awk '{print $4}')
19762
19763         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19764 }
19765 run_test 228b "idle OI blocks can be reused after MDT restart"
19766
19767 #LU-1881
19768 test_228c() {
19769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19770         remote_mds_nodsh && skip "remote MDS with nodsh"
19771         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19772
19773         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19774         local myDIR=$DIR/$tdir
19775
19776         mkdir -p $myDIR
19777         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19778         $LCTL set_param fail_loc=0x80001002
19779         # 20000 files can guarantee there are index nodes in the OI file
19780         createmany -o $myDIR/t- 20000
19781         $LCTL set_param fail_loc=0
19782         # The guard is current the largest FID holder
19783         touch $myDIR/guard
19784         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19785                     tr -d '[')
19786         local IDX=$(($SEQ % 64))
19787
19788         do_facet $SINGLEMDS sync
19789         # Make sure journal flushed.
19790         sleep 6
19791         local blk1=$(do_facet $SINGLEMDS \
19792                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19793                      grep Blockcount | awk '{print $4}')
19794
19795         # Remove old files, some OI blocks will become idle.
19796         unlinkmany $myDIR/t- 20000
19797         rm -f $myDIR/guard
19798         # The OI file should become empty now
19799
19800         # Create new files, idle OI blocks should be reused.
19801         createmany -o $myDIR/t- 2000
19802         do_facet $SINGLEMDS sync
19803         # Make sure journal flushed.
19804         sleep 6
19805         local blk2=$(do_facet $SINGLEMDS \
19806                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19807                      grep Blockcount | awk '{print $4}')
19808
19809         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19810 }
19811 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19812
19813 test_229() { # LU-2482, LU-3448
19814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19815         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19816         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19817                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19818
19819         rm -f $DIR/$tfile
19820
19821         # Create a file with a released layout and stripe count 2.
19822         $MULTIOP $DIR/$tfile H2c ||
19823                 error "failed to create file with released layout"
19824
19825         $LFS getstripe -v $DIR/$tfile
19826
19827         local pattern=$($LFS getstripe -L $DIR/$tfile)
19828         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19829
19830         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19831                 error "getstripe"
19832         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19833         stat $DIR/$tfile || error "failed to stat released file"
19834
19835         chown $RUNAS_ID $DIR/$tfile ||
19836                 error "chown $RUNAS_ID $DIR/$tfile failed"
19837
19838         chgrp $RUNAS_ID $DIR/$tfile ||
19839                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19840
19841         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19842         rm $DIR/$tfile || error "failed to remove released file"
19843 }
19844 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19845
19846 test_230a() {
19847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19850                 skip "Need MDS version at least 2.11.52"
19851
19852         local MDTIDX=1
19853
19854         test_mkdir $DIR/$tdir
19855         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19856         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19857         [ $mdt_idx -ne 0 ] &&
19858                 error "create local directory on wrong MDT $mdt_idx"
19859
19860         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19861                         error "create remote directory failed"
19862         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19863         [ $mdt_idx -ne $MDTIDX ] &&
19864                 error "create remote directory on wrong MDT $mdt_idx"
19865
19866         createmany -o $DIR/$tdir/test_230/t- 10 ||
19867                 error "create files on remote directory failed"
19868         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19869         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19870         rm -r $DIR/$tdir || error "unlink remote directory failed"
19871 }
19872 run_test 230a "Create remote directory and files under the remote directory"
19873
19874 test_230b() {
19875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19876         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19877         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19878                 skip "Need MDS version at least 2.11.52"
19879
19880         local MDTIDX=1
19881         local mdt_index
19882         local i
19883         local file
19884         local pid
19885         local stripe_count
19886         local migrate_dir=$DIR/$tdir/migrate_dir
19887         local other_dir=$DIR/$tdir/other_dir
19888
19889         test_mkdir $DIR/$tdir
19890         test_mkdir -i0 -c1 $migrate_dir
19891         test_mkdir -i0 -c1 $other_dir
19892         for ((i=0; i<10; i++)); do
19893                 mkdir -p $migrate_dir/dir_${i}
19894                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19895                         error "create files under remote dir failed $i"
19896         done
19897
19898         cp /etc/passwd $migrate_dir/$tfile
19899         cp /etc/passwd $other_dir/$tfile
19900         chattr +SAD $migrate_dir
19901         chattr +SAD $migrate_dir/$tfile
19902
19903         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19904         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19905         local old_dir_mode=$(stat -c%f $migrate_dir)
19906         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19907
19908         mkdir -p $migrate_dir/dir_default_stripe2
19909         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19910         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19911
19912         mkdir -p $other_dir
19913         ln $migrate_dir/$tfile $other_dir/luna
19914         ln $migrate_dir/$tfile $migrate_dir/sofia
19915         ln $other_dir/$tfile $migrate_dir/david
19916         ln -s $migrate_dir/$tfile $other_dir/zachary
19917         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19918         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19919
19920         local len
19921         local lnktgt
19922
19923         # inline symlink
19924         for len in 58 59 60; do
19925                 lnktgt=$(str_repeat 'l' $len)
19926                 touch $migrate_dir/$lnktgt
19927                 ln -s $lnktgt $migrate_dir/${len}char_ln
19928         done
19929
19930         # PATH_MAX
19931         for len in 4094 4095; do
19932                 lnktgt=$(str_repeat 'l' $len)
19933                 ln -s $lnktgt $migrate_dir/${len}char_ln
19934         done
19935
19936         # NAME_MAX
19937         for len in 254 255; do
19938                 touch $migrate_dir/$(str_repeat 'l' $len)
19939         done
19940
19941         $LFS migrate -m $MDTIDX $migrate_dir ||
19942                 error "fails on migrating remote dir to MDT1"
19943
19944         echo "migratate to MDT1, then checking.."
19945         for ((i = 0; i < 10; i++)); do
19946                 for file in $(find $migrate_dir/dir_${i}); do
19947                         mdt_index=$($LFS getstripe -m $file)
19948                         # broken symlink getstripe will fail
19949                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19950                                 error "$file is not on MDT${MDTIDX}"
19951                 done
19952         done
19953
19954         # the multiple link file should still in MDT0
19955         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19956         [ $mdt_index == 0 ] ||
19957                 error "$file is not on MDT${MDTIDX}"
19958
19959         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19960         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19961                 error " expect $old_dir_flag get $new_dir_flag"
19962
19963         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19964         [ "$old_file_flag" = "$new_file_flag" ] ||
19965                 error " expect $old_file_flag get $new_file_flag"
19966
19967         local new_dir_mode=$(stat -c%f $migrate_dir)
19968         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19969                 error "expect mode $old_dir_mode get $new_dir_mode"
19970
19971         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19972         [ "$old_file_mode" = "$new_file_mode" ] ||
19973                 error "expect mode $old_file_mode get $new_file_mode"
19974
19975         diff /etc/passwd $migrate_dir/$tfile ||
19976                 error "$tfile different after migration"
19977
19978         diff /etc/passwd $other_dir/luna ||
19979                 error "luna different after migration"
19980
19981         diff /etc/passwd $migrate_dir/sofia ||
19982                 error "sofia different after migration"
19983
19984         diff /etc/passwd $migrate_dir/david ||
19985                 error "david different after migration"
19986
19987         diff /etc/passwd $other_dir/zachary ||
19988                 error "zachary different after migration"
19989
19990         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19991                 error "${tfile}_ln different after migration"
19992
19993         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19994                 error "${tfile}_ln_other different after migration"
19995
19996         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19997         [ $stripe_count = 2 ] ||
19998                 error "dir strpe_count $d != 2 after migration."
19999
20000         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20001         [ $stripe_count = 2 ] ||
20002                 error "file strpe_count $d != 2 after migration."
20003
20004         #migrate back to MDT0
20005         MDTIDX=0
20006
20007         $LFS migrate -m $MDTIDX $migrate_dir ||
20008                 error "fails on migrating remote dir to MDT0"
20009
20010         echo "migrate back to MDT0, checking.."
20011         for file in $(find $migrate_dir); do
20012                 mdt_index=$($LFS getstripe -m $file)
20013                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20014                         error "$file is not on MDT${MDTIDX}"
20015         done
20016
20017         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20018         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20019                 error " expect $old_dir_flag get $new_dir_flag"
20020
20021         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20022         [ "$old_file_flag" = "$new_file_flag" ] ||
20023                 error " expect $old_file_flag get $new_file_flag"
20024
20025         local new_dir_mode=$(stat -c%f $migrate_dir)
20026         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20027                 error "expect mode $old_dir_mode get $new_dir_mode"
20028
20029         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20030         [ "$old_file_mode" = "$new_file_mode" ] ||
20031                 error "expect mode $old_file_mode get $new_file_mode"
20032
20033         diff /etc/passwd ${migrate_dir}/$tfile ||
20034                 error "$tfile different after migration"
20035
20036         diff /etc/passwd ${other_dir}/luna ||
20037                 error "luna different after migration"
20038
20039         diff /etc/passwd ${migrate_dir}/sofia ||
20040                 error "sofia different after migration"
20041
20042         diff /etc/passwd ${other_dir}/zachary ||
20043                 error "zachary different after migration"
20044
20045         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20046                 error "${tfile}_ln different after migration"
20047
20048         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20049                 error "${tfile}_ln_other different after migration"
20050
20051         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20052         [ $stripe_count = 2 ] ||
20053                 error "dir strpe_count $d != 2 after migration."
20054
20055         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20056         [ $stripe_count = 2 ] ||
20057                 error "file strpe_count $d != 2 after migration."
20058
20059         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20060 }
20061 run_test 230b "migrate directory"
20062
20063 test_230c() {
20064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20066         remote_mds_nodsh && skip "remote MDS with nodsh"
20067         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20068                 skip "Need MDS version at least 2.11.52"
20069
20070         local MDTIDX=1
20071         local total=3
20072         local mdt_index
20073         local file
20074         local migrate_dir=$DIR/$tdir/migrate_dir
20075
20076         #If migrating directory fails in the middle, all entries of
20077         #the directory is still accessiable.
20078         test_mkdir $DIR/$tdir
20079         test_mkdir -i0 -c1 $migrate_dir
20080         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20081         stat $migrate_dir
20082         createmany -o $migrate_dir/f $total ||
20083                 error "create files under ${migrate_dir} failed"
20084
20085         # fail after migrating top dir, and this will fail only once, so the
20086         # first sub file migration will fail (currently f3), others succeed.
20087         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20088         do_facet mds1 lctl set_param fail_loc=0x1801
20089         local t=$(ls $migrate_dir | wc -l)
20090         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20091                 error "migrate should fail"
20092         local u=$(ls $migrate_dir | wc -l)
20093         [ "$u" == "$t" ] || error "$u != $t during migration"
20094
20095         # add new dir/file should succeed
20096         mkdir $migrate_dir/dir ||
20097                 error "mkdir failed under migrating directory"
20098         touch $migrate_dir/file ||
20099                 error "create file failed under migrating directory"
20100
20101         # add file with existing name should fail
20102         for file in $migrate_dir/f*; do
20103                 stat $file > /dev/null || error "stat $file failed"
20104                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20105                         error "open(O_CREAT|O_EXCL) $file should fail"
20106                 $MULTIOP $file m && error "create $file should fail"
20107                 touch $DIR/$tdir/remote_dir/$tfile ||
20108                         error "touch $tfile failed"
20109                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20110                         error "link $file should fail"
20111                 mdt_index=$($LFS getstripe -m $file)
20112                 if [ $mdt_index == 0 ]; then
20113                         # file failed to migrate is not allowed to rename to
20114                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20115                                 error "rename to $file should fail"
20116                 else
20117                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20118                                 error "rename to $file failed"
20119                 fi
20120                 echo hello >> $file || error "write $file failed"
20121         done
20122
20123         # resume migration with different options should fail
20124         $LFS migrate -m 0 $migrate_dir &&
20125                 error "migrate -m 0 $migrate_dir should fail"
20126
20127         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20128                 error "migrate -c 2 $migrate_dir should fail"
20129
20130         # resume migration should succeed
20131         $LFS migrate -m $MDTIDX $migrate_dir ||
20132                 error "migrate $migrate_dir failed"
20133
20134         echo "Finish migration, then checking.."
20135         for file in $(find $migrate_dir); do
20136                 mdt_index=$($LFS getstripe -m $file)
20137                 [ $mdt_index == $MDTIDX ] ||
20138                         error "$file is not on MDT${MDTIDX}"
20139         done
20140
20141         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20142 }
20143 run_test 230c "check directory accessiblity if migration failed"
20144
20145 test_230d() {
20146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20149                 skip "Need MDS version at least 2.11.52"
20150         # LU-11235
20151         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20152
20153         local migrate_dir=$DIR/$tdir/migrate_dir
20154         local old_index
20155         local new_index
20156         local old_count
20157         local new_count
20158         local new_hash
20159         local mdt_index
20160         local i
20161         local j
20162
20163         old_index=$((RANDOM % MDSCOUNT))
20164         old_count=$((MDSCOUNT - old_index))
20165         new_index=$((RANDOM % MDSCOUNT))
20166         new_count=$((MDSCOUNT - new_index))
20167         new_hash=1 # for all_char
20168
20169         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20170         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20171
20172         test_mkdir $DIR/$tdir
20173         test_mkdir -i $old_index -c $old_count $migrate_dir
20174
20175         for ((i=0; i<100; i++)); do
20176                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20177                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20178                         error "create files under remote dir failed $i"
20179         done
20180
20181         echo -n "Migrate from MDT$old_index "
20182         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20183         echo -n "to MDT$new_index"
20184         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20185         echo
20186
20187         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20188         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20189                 error "migrate remote dir error"
20190
20191         echo "Finish migration, then checking.."
20192         for file in $(find $migrate_dir -maxdepth 1); do
20193                 mdt_index=$($LFS getstripe -m $file)
20194                 if [ $mdt_index -lt $new_index ] ||
20195                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20196                         error "$file is on MDT$mdt_index"
20197                 fi
20198         done
20199
20200         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20201 }
20202 run_test 230d "check migrate big directory"
20203
20204 test_230e() {
20205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20207         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20208                 skip "Need MDS version at least 2.11.52"
20209
20210         local i
20211         local j
20212         local a_fid
20213         local b_fid
20214
20215         mkdir_on_mdt0 $DIR/$tdir
20216         mkdir $DIR/$tdir/migrate_dir
20217         mkdir $DIR/$tdir/other_dir
20218         touch $DIR/$tdir/migrate_dir/a
20219         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20220         ls $DIR/$tdir/other_dir
20221
20222         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20223                 error "migrate dir fails"
20224
20225         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20226         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20227
20228         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20229         [ $mdt_index == 0 ] || error "a is not on MDT0"
20230
20231         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20232                 error "migrate dir fails"
20233
20234         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20235         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20236
20237         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20238         [ $mdt_index == 1 ] || error "a is not on MDT1"
20239
20240         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20241         [ $mdt_index == 1 ] || error "b is not on MDT1"
20242
20243         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20244         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20245
20246         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20247
20248         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20249 }
20250 run_test 230e "migrate mulitple local link files"
20251
20252 test_230f() {
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20256                 skip "Need MDS version at least 2.11.52"
20257
20258         local a_fid
20259         local ln_fid
20260
20261         mkdir -p $DIR/$tdir
20262         mkdir $DIR/$tdir/migrate_dir
20263         $LFS mkdir -i1 $DIR/$tdir/other_dir
20264         touch $DIR/$tdir/migrate_dir/a
20265         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20266         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20267         ls $DIR/$tdir/other_dir
20268
20269         # a should be migrated to MDT1, since no other links on MDT0
20270         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20271                 error "#1 migrate dir fails"
20272         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20273         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20274         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20275         [ $mdt_index == 1 ] || error "a is not on MDT1"
20276
20277         # a should stay on MDT1, because it is a mulitple link file
20278         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20279                 error "#2 migrate dir fails"
20280         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20281         [ $mdt_index == 1 ] || error "a is not on MDT1"
20282
20283         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20284                 error "#3 migrate dir fails"
20285
20286         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20287         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20288         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20289
20290         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20291         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20292
20293         # a should be migrated to MDT0, since no other links on MDT1
20294         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20295                 error "#4 migrate dir fails"
20296         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20297         [ $mdt_index == 0 ] || error "a is not on MDT0"
20298
20299         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20300 }
20301 run_test 230f "migrate mulitple remote link files"
20302
20303 test_230g() {
20304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20307                 skip "Need MDS version at least 2.11.52"
20308
20309         mkdir -p $DIR/$tdir/migrate_dir
20310
20311         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20312                 error "migrating dir to non-exist MDT succeeds"
20313         true
20314 }
20315 run_test 230g "migrate dir to non-exist MDT"
20316
20317 test_230h() {
20318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20320         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20321                 skip "Need MDS version at least 2.11.52"
20322
20323         local mdt_index
20324
20325         mkdir -p $DIR/$tdir/migrate_dir
20326
20327         $LFS migrate -m1 $DIR &&
20328                 error "migrating mountpoint1 should fail"
20329
20330         $LFS migrate -m1 $DIR/$tdir/.. &&
20331                 error "migrating mountpoint2 should fail"
20332
20333         # same as mv
20334         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20335                 error "migrating $tdir/migrate_dir/.. should fail"
20336
20337         true
20338 }
20339 run_test 230h "migrate .. and root"
20340
20341 test_230i() {
20342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20344         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20345                 skip "Need MDS version at least 2.11.52"
20346
20347         mkdir -p $DIR/$tdir/migrate_dir
20348
20349         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20350                 error "migration fails with a tailing slash"
20351
20352         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20353                 error "migration fails with two tailing slashes"
20354 }
20355 run_test 230i "lfs migrate -m tolerates trailing slashes"
20356
20357 test_230j() {
20358         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20359         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20360                 skip "Need MDS version at least 2.11.52"
20361
20362         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20363         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20364                 error "create $tfile failed"
20365         cat /etc/passwd > $DIR/$tdir/$tfile
20366
20367         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20368
20369         cmp /etc/passwd $DIR/$tdir/$tfile ||
20370                 error "DoM file mismatch after migration"
20371 }
20372 run_test 230j "DoM file data not changed after dir migration"
20373
20374 test_230k() {
20375         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20376         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20377                 skip "Need MDS version at least 2.11.56"
20378
20379         local total=20
20380         local files_on_starting_mdt=0
20381
20382         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20383         $LFS getdirstripe $DIR/$tdir
20384         for i in $(seq $total); do
20385                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20386                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20387                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20388         done
20389
20390         echo "$files_on_starting_mdt files on MDT0"
20391
20392         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20393         $LFS getdirstripe $DIR/$tdir
20394
20395         files_on_starting_mdt=0
20396         for i in $(seq $total); do
20397                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20398                         error "file $tfile.$i mismatch after migration"
20399                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20400                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20401         done
20402
20403         echo "$files_on_starting_mdt files on MDT1 after migration"
20404         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20405
20406         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20407         $LFS getdirstripe $DIR/$tdir
20408
20409         files_on_starting_mdt=0
20410         for i in $(seq $total); do
20411                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20412                         error "file $tfile.$i mismatch after 2nd migration"
20413                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20414                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20415         done
20416
20417         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20418         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20419
20420         true
20421 }
20422 run_test 230k "file data not changed after dir migration"
20423
20424 test_230l() {
20425         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20426         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20427                 skip "Need MDS version at least 2.11.56"
20428
20429         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20430         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20431                 error "create files under remote dir failed $i"
20432         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20433 }
20434 run_test 230l "readdir between MDTs won't crash"
20435
20436 test_230m() {
20437         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20438         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20439                 skip "Need MDS version at least 2.11.56"
20440
20441         local MDTIDX=1
20442         local mig_dir=$DIR/$tdir/migrate_dir
20443         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20444         local shortstr="b"
20445         local val
20446
20447         echo "Creating files and dirs with xattrs"
20448         test_mkdir $DIR/$tdir
20449         test_mkdir -i0 -c1 $mig_dir
20450         mkdir $mig_dir/dir
20451         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20452                 error "cannot set xattr attr1 on dir"
20453         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20454                 error "cannot set xattr attr2 on dir"
20455         touch $mig_dir/dir/f0
20456         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20457                 error "cannot set xattr attr1 on file"
20458         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20459                 error "cannot set xattr attr2 on file"
20460         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20461         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20462         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20463         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20464         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20465         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20466         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20467         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20468         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20469
20470         echo "Migrating to MDT1"
20471         $LFS migrate -m $MDTIDX $mig_dir ||
20472                 error "fails on migrating dir to MDT1"
20473
20474         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20475         echo "Checking xattrs"
20476         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20477         [ "$val" = $longstr ] ||
20478                 error "expecting xattr1 $longstr on dir, found $val"
20479         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20480         [ "$val" = $shortstr ] ||
20481                 error "expecting xattr2 $shortstr on dir, found $val"
20482         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20483         [ "$val" = $longstr ] ||
20484                 error "expecting xattr1 $longstr on file, found $val"
20485         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20486         [ "$val" = $shortstr ] ||
20487                 error "expecting xattr2 $shortstr on file, found $val"
20488 }
20489 run_test 230m "xattrs not changed after dir migration"
20490
20491 test_230n() {
20492         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20493         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20494                 skip "Need MDS version at least 2.13.53"
20495
20496         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20497         cat /etc/hosts > $DIR/$tdir/$tfile
20498         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20499         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20500
20501         cmp /etc/hosts $DIR/$tdir/$tfile ||
20502                 error "File data mismatch after migration"
20503 }
20504 run_test 230n "Dir migration with mirrored file"
20505
20506 test_230o() {
20507         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20508         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20509                 skip "Need MDS version at least 2.13.52"
20510
20511         local mdts=$(comma_list $(mdts_nodes))
20512         local timeout=100
20513         local restripe_status
20514         local delta
20515         local i
20516
20517         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20518
20519         # in case "crush" hash type is not set
20520         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20521
20522         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20523                            mdt.*MDT0000.enable_dir_restripe)
20524         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20525         stack_trap "do_nodes $mdts $LCTL set_param \
20526                     mdt.*.enable_dir_restripe=$restripe_status"
20527
20528         mkdir $DIR/$tdir
20529         createmany -m $DIR/$tdir/f 100 ||
20530                 error "create files under remote dir failed $i"
20531         createmany -d $DIR/$tdir/d 100 ||
20532                 error "create dirs under remote dir failed $i"
20533
20534         for i in $(seq 2 $MDSCOUNT); do
20535                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20536                 $LFS setdirstripe -c $i $DIR/$tdir ||
20537                         error "split -c $i $tdir failed"
20538                 wait_update $HOSTNAME \
20539                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20540                         error "dir split not finished"
20541                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20542                         awk '/migrate/ {sum += $2} END { print sum }')
20543                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20544                 # delta is around total_files/stripe_count
20545                 (( $delta < 200 / (i - 1) + 4 )) ||
20546                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20547         done
20548 }
20549 run_test 230o "dir split"
20550
20551 test_230p() {
20552         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20553         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20554                 skip "Need MDS version at least 2.13.52"
20555
20556         local mdts=$(comma_list $(mdts_nodes))
20557         local timeout=100
20558         local restripe_status
20559         local delta
20560         local c
20561
20562         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20563
20564         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20565
20566         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20567                            mdt.*MDT0000.enable_dir_restripe)
20568         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20569         stack_trap "do_nodes $mdts $LCTL set_param \
20570                     mdt.*.enable_dir_restripe=$restripe_status"
20571
20572         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20573         createmany -m $DIR/$tdir/f 100 ||
20574                 error "create files under remote dir failed"
20575         createmany -d $DIR/$tdir/d 100 ||
20576                 error "create dirs under remote dir failed"
20577
20578         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20579                 local mdt_hash="crush"
20580
20581                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20582                 $LFS setdirstripe -c $c $DIR/$tdir ||
20583                         error "split -c $c $tdir failed"
20584                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20585                         mdt_hash="$mdt_hash,fixed"
20586                 elif [ $c -eq 1 ]; then
20587                         mdt_hash="none"
20588                 fi
20589                 wait_update $HOSTNAME \
20590                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20591                         error "dir merge not finished"
20592                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20593                         awk '/migrate/ {sum += $2} END { print sum }')
20594                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20595                 # delta is around total_files/stripe_count
20596                 (( delta < 200 / c + 4 )) ||
20597                         error "$delta files migrated >= $((200 / c + 4))"
20598         done
20599 }
20600 run_test 230p "dir merge"
20601
20602 test_230q() {
20603         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20604         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20605                 skip "Need MDS version at least 2.13.52"
20606
20607         local mdts=$(comma_list $(mdts_nodes))
20608         local saved_threshold=$(do_facet mds1 \
20609                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20610         local saved_delta=$(do_facet mds1 \
20611                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20612         local threshold=100
20613         local delta=2
20614         local total=0
20615         local stripe_count=0
20616         local stripe_index
20617         local nr_files
20618         local create
20619
20620         # test with fewer files on ZFS
20621         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20622
20623         stack_trap "do_nodes $mdts $LCTL set_param \
20624                     mdt.*.dir_split_count=$saved_threshold"
20625         stack_trap "do_nodes $mdts $LCTL set_param \
20626                     mdt.*.dir_split_delta=$saved_delta"
20627         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20628         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20629         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20630         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20631         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20632         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20633
20634         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20635         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20636
20637         create=$((threshold * 3 / 2))
20638         while [ $stripe_count -lt $MDSCOUNT ]; do
20639                 createmany -m $DIR/$tdir/f $total $create ||
20640                         error "create sub files failed"
20641                 stat $DIR/$tdir > /dev/null
20642                 total=$((total + create))
20643                 stripe_count=$((stripe_count + delta))
20644                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20645
20646                 wait_update $HOSTNAME \
20647                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20648                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20649
20650                 wait_update $HOSTNAME \
20651                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20652                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20653
20654                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20655                 echo "$nr_files/$total files on MDT$stripe_index after split"
20656                 # allow 10% margin of imbalance with crush hash
20657                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20658                         error "$nr_files files on MDT$stripe_index after split"
20659
20660                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20661                 [ $nr_files -eq $total ] ||
20662                         error "total sub files $nr_files != $total"
20663         done
20664
20665         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20666
20667         echo "fixed layout directory won't auto split"
20668         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20669         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20670                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20671         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20672                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20673 }
20674 run_test 230q "dir auto split"
20675
20676 test_230r() {
20677         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20678         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20679         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20680                 skip "Need MDS version at least 2.13.54"
20681
20682         # maximum amount of local locks:
20683         # parent striped dir - 2 locks
20684         # new stripe in parent to migrate to - 1 lock
20685         # source and target - 2 locks
20686         # Total 5 locks for regular file
20687         mkdir -p $DIR/$tdir
20688         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20689         touch $DIR/$tdir/dir1/eee
20690
20691         # create 4 hardlink for 4 more locks
20692         # Total: 9 locks > RS_MAX_LOCKS (8)
20693         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20694         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20695         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20696         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20697         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20698         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20699         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20700         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20701
20702         cancel_lru_locks mdc
20703
20704         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20705                 error "migrate dir fails"
20706
20707         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20708 }
20709 run_test 230r "migrate with too many local locks"
20710
20711 test_230s() {
20712         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20713                 skip "Need MDS version at least 2.14.52"
20714
20715         local mdts=$(comma_list $(mdts_nodes))
20716         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20717                                 mdt.*MDT0000.enable_dir_restripe)
20718
20719         stack_trap "do_nodes $mdts $LCTL set_param \
20720                     mdt.*.enable_dir_restripe=$restripe_status"
20721
20722         local st
20723         for st in 0 1; do
20724                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20725                 test_mkdir $DIR/$tdir
20726                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20727                         error "$LFS mkdir should return EEXIST if target exists"
20728                 rmdir $DIR/$tdir
20729         done
20730 }
20731 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20732
20733 test_230t()
20734 {
20735         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20736         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20737                 skip "Need MDS version at least 2.14.50"
20738
20739         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20740         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20741         $LFS project -p 1 -s $DIR/$tdir ||
20742                 error "set $tdir project id failed"
20743         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20744                 error "set subdir project id failed"
20745         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20746 }
20747 run_test 230t "migrate directory with project ID set"
20748
20749 test_230u()
20750 {
20751         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20752         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20753                 skip "Need MDS version at least 2.14.53"
20754
20755         local count
20756
20757         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20758         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20759         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20760         for i in $(seq 0 $((MDSCOUNT - 1))); do
20761                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20762                 echo "$count dirs migrated to MDT$i"
20763         done
20764         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20765         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20766 }
20767 run_test 230u "migrate directory by QOS"
20768
20769 test_230v()
20770 {
20771         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20772         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20773                 skip "Need MDS version at least 2.14.53"
20774
20775         local count
20776
20777         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20778         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20779         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20780         for i in $(seq 0 $((MDSCOUNT - 1))); do
20781                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20782                 echo "$count subdirs migrated to MDT$i"
20783                 (( i == 3 )) && (( count > 0 )) &&
20784                         error "subdir shouldn't be migrated to MDT3"
20785         done
20786         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20787         (( count == 3 )) || error "dirs migrated to $count MDTs"
20788 }
20789 run_test 230v "subdir migrated to the MDT where its parent is located"
20790
20791 test_230w() {
20792         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20793         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20794                 skip "Need MDS version at least 2.15.0"
20795
20796         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20797         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20798         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20799
20800         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20801                 error "migrate failed"
20802
20803         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20804                 error "$tdir stripe count mismatch"
20805
20806         for i in $(seq 0 9); do
20807                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20808                         error "d$i is striped"
20809         done
20810 }
20811 run_test 230w "non-recursive mode dir migration"
20812
20813 test_231a()
20814 {
20815         # For simplicity this test assumes that max_pages_per_rpc
20816         # is the same across all OSCs
20817         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20818         local bulk_size=$((max_pages * PAGE_SIZE))
20819         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20820                                        head -n 1)
20821
20822         mkdir -p $DIR/$tdir
20823         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20824                 error "failed to set stripe with -S ${brw_size}M option"
20825
20826         # clear the OSC stats
20827         $LCTL set_param osc.*.stats=0 &>/dev/null
20828         stop_writeback
20829
20830         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20831         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20832                 oflag=direct &>/dev/null || error "dd failed"
20833
20834         sync; sleep 1; sync # just to be safe
20835         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20836         if [ x$nrpcs != "x1" ]; then
20837                 $LCTL get_param osc.*.stats
20838                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20839         fi
20840
20841         start_writeback
20842         # Drop the OSC cache, otherwise we will read from it
20843         cancel_lru_locks osc
20844
20845         # clear the OSC stats
20846         $LCTL set_param osc.*.stats=0 &>/dev/null
20847
20848         # Client reads $bulk_size.
20849         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20850                 iflag=direct &>/dev/null || error "dd failed"
20851
20852         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20853         if [ x$nrpcs != "x1" ]; then
20854                 $LCTL get_param osc.*.stats
20855                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20856         fi
20857 }
20858 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20859
20860 test_231b() {
20861         mkdir -p $DIR/$tdir
20862         local i
20863         for i in {0..1023}; do
20864                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20865                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20866                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20867         done
20868         sync
20869 }
20870 run_test 231b "must not assert on fully utilized OST request buffer"
20871
20872 test_232a() {
20873         mkdir -p $DIR/$tdir
20874         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20875
20876         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20877         do_facet ost1 $LCTL set_param fail_loc=0x31c
20878
20879         # ignore dd failure
20880         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20881
20882         do_facet ost1 $LCTL set_param fail_loc=0
20883         umount_client $MOUNT || error "umount failed"
20884         mount_client $MOUNT || error "mount failed"
20885         stop ost1 || error "cannot stop ost1"
20886         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20887 }
20888 run_test 232a "failed lock should not block umount"
20889
20890 test_232b() {
20891         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20892                 skip "Need MDS version at least 2.10.58"
20893
20894         mkdir -p $DIR/$tdir
20895         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20896         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20897         sync
20898         cancel_lru_locks osc
20899
20900         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20901         do_facet ost1 $LCTL set_param fail_loc=0x31c
20902
20903         # ignore failure
20904         $LFS data_version $DIR/$tdir/$tfile || true
20905
20906         do_facet ost1 $LCTL set_param fail_loc=0
20907         umount_client $MOUNT || error "umount failed"
20908         mount_client $MOUNT || error "mount failed"
20909         stop ost1 || error "cannot stop ost1"
20910         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20911 }
20912 run_test 232b "failed data version lock should not block umount"
20913
20914 test_233a() {
20915         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20916                 skip "Need MDS version at least 2.3.64"
20917         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20918
20919         local fid=$($LFS path2fid $MOUNT)
20920
20921         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20922                 error "cannot access $MOUNT using its FID '$fid'"
20923 }
20924 run_test 233a "checking that OBF of the FS root succeeds"
20925
20926 test_233b() {
20927         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20928                 skip "Need MDS version at least 2.5.90"
20929         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20930
20931         local fid=$($LFS path2fid $MOUNT/.lustre)
20932
20933         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20934                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20935
20936         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20937         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20938                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20939 }
20940 run_test 233b "checking that OBF of the FS .lustre succeeds"
20941
20942 test_234() {
20943         local p="$TMP/sanityN-$TESTNAME.parameters"
20944         save_lustre_params client "llite.*.xattr_cache" > $p
20945         lctl set_param llite.*.xattr_cache 1 ||
20946                 skip_env "xattr cache is not supported"
20947
20948         mkdir -p $DIR/$tdir || error "mkdir failed"
20949         touch $DIR/$tdir/$tfile || error "touch failed"
20950         # OBD_FAIL_LLITE_XATTR_ENOMEM
20951         $LCTL set_param fail_loc=0x1405
20952         getfattr -n user.attr $DIR/$tdir/$tfile &&
20953                 error "getfattr should have failed with ENOMEM"
20954         $LCTL set_param fail_loc=0x0
20955         rm -rf $DIR/$tdir
20956
20957         restore_lustre_params < $p
20958         rm -f $p
20959 }
20960 run_test 234 "xattr cache should not crash on ENOMEM"
20961
20962 test_235() {
20963         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20964                 skip "Need MDS version at least 2.4.52"
20965
20966         flock_deadlock $DIR/$tfile
20967         local RC=$?
20968         case $RC in
20969                 0)
20970                 ;;
20971                 124) error "process hangs on a deadlock"
20972                 ;;
20973                 *) error "error executing flock_deadlock $DIR/$tfile"
20974                 ;;
20975         esac
20976 }
20977 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20978
20979 #LU-2935
20980 test_236() {
20981         check_swap_layouts_support
20982
20983         local ref1=/etc/passwd
20984         local ref2=/etc/group
20985         local file1=$DIR/$tdir/f1
20986         local file2=$DIR/$tdir/f2
20987
20988         test_mkdir -c1 $DIR/$tdir
20989         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20990         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20991         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20992         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20993         local fd=$(free_fd)
20994         local cmd="exec $fd<>$file2"
20995         eval $cmd
20996         rm $file2
20997         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20998                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20999         cmd="exec $fd>&-"
21000         eval $cmd
21001         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21002
21003         #cleanup
21004         rm -rf $DIR/$tdir
21005 }
21006 run_test 236 "Layout swap on open unlinked file"
21007
21008 # LU-4659 linkea consistency
21009 test_238() {
21010         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21011                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21012                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21013                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21014
21015         touch $DIR/$tfile
21016         ln $DIR/$tfile $DIR/$tfile.lnk
21017         touch $DIR/$tfile.new
21018         mv $DIR/$tfile.new $DIR/$tfile
21019         local fid1=$($LFS path2fid $DIR/$tfile)
21020         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21021         local path1=$($LFS fid2path $FSNAME "$fid1")
21022         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21023         local path2=$($LFS fid2path $FSNAME "$fid2")
21024         [ $tfile.lnk == $path2 ] ||
21025                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21026         rm -f $DIR/$tfile*
21027 }
21028 run_test 238 "Verify linkea consistency"
21029
21030 test_239A() { # was test_239
21031         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21032                 skip "Need MDS version at least 2.5.60"
21033
21034         local list=$(comma_list $(mdts_nodes))
21035
21036         mkdir -p $DIR/$tdir
21037         createmany -o $DIR/$tdir/f- 5000
21038         unlinkmany $DIR/$tdir/f- 5000
21039         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21040                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21041         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21042                         osp.*MDT*.sync_in_flight" | calc_sum)
21043         [ "$changes" -eq 0 ] || error "$changes not synced"
21044 }
21045 run_test 239A "osp_sync test"
21046
21047 test_239a() { #LU-5297
21048         remote_mds_nodsh && skip "remote MDS with nodsh"
21049
21050         touch $DIR/$tfile
21051         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21052         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21053         chgrp $RUNAS_GID $DIR/$tfile
21054         wait_delete_completed
21055 }
21056 run_test 239a "process invalid osp sync record correctly"
21057
21058 test_239b() { #LU-5297
21059         remote_mds_nodsh && skip "remote MDS with nodsh"
21060
21061         touch $DIR/$tfile1
21062         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21063         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21064         chgrp $RUNAS_GID $DIR/$tfile1
21065         wait_delete_completed
21066         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21067         touch $DIR/$tfile2
21068         chgrp $RUNAS_GID $DIR/$tfile2
21069         wait_delete_completed
21070 }
21071 run_test 239b "process osp sync record with ENOMEM error correctly"
21072
21073 test_240() {
21074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21075         remote_mds_nodsh && skip "remote MDS with nodsh"
21076
21077         mkdir -p $DIR/$tdir
21078
21079         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21080                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21081         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21082                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21083
21084         umount_client $MOUNT || error "umount failed"
21085         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21086         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21087         mount_client $MOUNT || error "failed to mount client"
21088
21089         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21090         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21091 }
21092 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21093
21094 test_241_bio() {
21095         local count=$1
21096         local bsize=$2
21097
21098         for LOOP in $(seq $count); do
21099                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21100                 cancel_lru_locks $OSC || true
21101         done
21102 }
21103
21104 test_241_dio() {
21105         local count=$1
21106         local bsize=$2
21107
21108         for LOOP in $(seq $1); do
21109                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21110                         2>/dev/null
21111         done
21112 }
21113
21114 test_241a() { # was test_241
21115         local bsize=$PAGE_SIZE
21116
21117         (( bsize < 40960 )) && bsize=40960
21118         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21119         ls -la $DIR/$tfile
21120         cancel_lru_locks $OSC
21121         test_241_bio 1000 $bsize &
21122         PID=$!
21123         test_241_dio 1000 $bsize
21124         wait $PID
21125 }
21126 run_test 241a "bio vs dio"
21127
21128 test_241b() {
21129         local bsize=$PAGE_SIZE
21130
21131         (( bsize < 40960 )) && bsize=40960
21132         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21133         ls -la $DIR/$tfile
21134         test_241_dio 1000 $bsize &
21135         PID=$!
21136         test_241_dio 1000 $bsize
21137         wait $PID
21138 }
21139 run_test 241b "dio vs dio"
21140
21141 test_242() {
21142         remote_mds_nodsh && skip "remote MDS with nodsh"
21143
21144         mkdir_on_mdt0 $DIR/$tdir
21145         touch $DIR/$tdir/$tfile
21146
21147         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21148         do_facet mds1 lctl set_param fail_loc=0x105
21149         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21150
21151         do_facet mds1 lctl set_param fail_loc=0
21152         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21153 }
21154 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21155
21156 test_243()
21157 {
21158         test_mkdir $DIR/$tdir
21159         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21160 }
21161 run_test 243 "various group lock tests"
21162
21163 test_244a()
21164 {
21165         test_mkdir $DIR/$tdir
21166         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21167         sendfile_grouplock $DIR/$tdir/$tfile || \
21168                 error "sendfile+grouplock failed"
21169         rm -rf $DIR/$tdir
21170 }
21171 run_test 244a "sendfile with group lock tests"
21172
21173 test_244b()
21174 {
21175         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21176
21177         local threads=50
21178         local size=$((1024*1024))
21179
21180         test_mkdir $DIR/$tdir
21181         for i in $(seq 1 $threads); do
21182                 local file=$DIR/$tdir/file_$((i / 10))
21183                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21184                 local pids[$i]=$!
21185         done
21186         for i in $(seq 1 $threads); do
21187                 wait ${pids[$i]}
21188         done
21189 }
21190 run_test 244b "multi-threaded write with group lock"
21191
21192 test_245a() {
21193         local flagname="multi_mod_rpcs"
21194         local connect_data_name="max_mod_rpcs"
21195         local out
21196
21197         # check if multiple modify RPCs flag is set
21198         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21199                 grep "connect_flags:")
21200         echo "$out"
21201
21202         echo "$out" | grep -qw $flagname
21203         if [ $? -ne 0 ]; then
21204                 echo "connect flag $flagname is not set"
21205                 return
21206         fi
21207
21208         # check if multiple modify RPCs data is set
21209         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21210         echo "$out"
21211
21212         echo "$out" | grep -qw $connect_data_name ||
21213                 error "import should have connect data $connect_data_name"
21214 }
21215 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21216
21217 test_245b() {
21218         local flagname="multi_mod_rpcs"
21219         local connect_data_name="max_mod_rpcs"
21220         local out
21221
21222         remote_mds_nodsh && skip "remote MDS with nodsh"
21223         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21224
21225         # check if multiple modify RPCs flag is set
21226         out=$(do_facet mds1 \
21227               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21228               grep "connect_flags:")
21229         echo "$out"
21230
21231         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21232
21233         # check if multiple modify RPCs data is set
21234         out=$(do_facet mds1 \
21235               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21236
21237         [[ "$out" =~ $connect_data_name ]] ||
21238                 {
21239                         echo "$out"
21240                         error "missing connect data $connect_data_name"
21241                 }
21242 }
21243 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21244
21245 cleanup_247() {
21246         local submount=$1
21247
21248         trap 0
21249         umount_client $submount
21250         rmdir $submount
21251 }
21252
21253 test_247a() {
21254         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21255                 grep -q subtree ||
21256                 skip_env "Fileset feature is not supported"
21257
21258         local submount=${MOUNT}_$tdir
21259
21260         mkdir $MOUNT/$tdir
21261         mkdir -p $submount || error "mkdir $submount failed"
21262         FILESET="$FILESET/$tdir" mount_client $submount ||
21263                 error "mount $submount failed"
21264         trap "cleanup_247 $submount" EXIT
21265         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21266         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21267                 error "read $MOUNT/$tdir/$tfile failed"
21268         cleanup_247 $submount
21269 }
21270 run_test 247a "mount subdir as fileset"
21271
21272 test_247b() {
21273         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21274                 skip_env "Fileset feature is not supported"
21275
21276         local submount=${MOUNT}_$tdir
21277
21278         rm -rf $MOUNT/$tdir
21279         mkdir -p $submount || error "mkdir $submount failed"
21280         SKIP_FILESET=1
21281         FILESET="$FILESET/$tdir" mount_client $submount &&
21282                 error "mount $submount should fail"
21283         rmdir $submount
21284 }
21285 run_test 247b "mount subdir that dose not exist"
21286
21287 test_247c() {
21288         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21289                 skip_env "Fileset feature is not supported"
21290
21291         local submount=${MOUNT}_$tdir
21292
21293         mkdir -p $MOUNT/$tdir/dir1
21294         mkdir -p $submount || error "mkdir $submount failed"
21295         trap "cleanup_247 $submount" EXIT
21296         FILESET="$FILESET/$tdir" mount_client $submount ||
21297                 error "mount $submount failed"
21298         local fid=$($LFS path2fid $MOUNT/)
21299         $LFS fid2path $submount $fid && error "fid2path should fail"
21300         cleanup_247 $submount
21301 }
21302 run_test 247c "running fid2path outside subdirectory root"
21303
21304 test_247d() {
21305         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21306                 skip "Fileset feature is not supported"
21307
21308         local submount=${MOUNT}_$tdir
21309
21310         mkdir -p $MOUNT/$tdir/dir1
21311         mkdir -p $submount || error "mkdir $submount failed"
21312         FILESET="$FILESET/$tdir" mount_client $submount ||
21313                 error "mount $submount failed"
21314         trap "cleanup_247 $submount" EXIT
21315
21316         local td=$submount/dir1
21317         local fid=$($LFS path2fid $td)
21318         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21319
21320         # check that we get the same pathname back
21321         local rootpath
21322         local found
21323         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21324                 echo "$rootpath $fid"
21325                 found=$($LFS fid2path $rootpath "$fid")
21326                 [ -n "$found" ] || error "fid2path should succeed"
21327                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21328         done
21329         # check wrong root path format
21330         rootpath=$submount"_wrong"
21331         found=$($LFS fid2path $rootpath "$fid")
21332         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21333
21334         cleanup_247 $submount
21335 }
21336 run_test 247d "running fid2path inside subdirectory root"
21337
21338 # LU-8037
21339 test_247e() {
21340         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21341                 grep -q subtree ||
21342                 skip "Fileset feature is not supported"
21343
21344         local submount=${MOUNT}_$tdir
21345
21346         mkdir $MOUNT/$tdir
21347         mkdir -p $submount || error "mkdir $submount failed"
21348         FILESET="$FILESET/.." mount_client $submount &&
21349                 error "mount $submount should fail"
21350         rmdir $submount
21351 }
21352 run_test 247e "mount .. as fileset"
21353
21354 test_247f() {
21355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21356         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21357                 skip "Need at least version 2.13.52"
21358         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21359                 skip "Need at least version 2.14.50"
21360         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21361                 grep -q subtree ||
21362                 skip "Fileset feature is not supported"
21363
21364         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21365         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21366                 error "mkdir remote failed"
21367         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21368                 error "mkdir remote/subdir failed"
21369         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21370                 error "mkdir striped failed"
21371         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21372
21373         local submount=${MOUNT}_$tdir
21374
21375         mkdir -p $submount || error "mkdir $submount failed"
21376         stack_trap "rmdir $submount"
21377
21378         local dir
21379         local stat
21380         local fileset=$FILESET
21381         local mdts=$(comma_list $(mdts_nodes))
21382
21383         stat=$(do_facet mds1 $LCTL get_param -n \
21384                 mdt.*MDT0000.enable_remote_subdir_mount)
21385         stack_trap "do_nodes $mdts $LCTL set_param \
21386                 mdt.*.enable_remote_subdir_mount=$stat"
21387
21388         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21389         stack_trap "umount_client $submount"
21390         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21391                 error "mount remote dir $dir should fail"
21392
21393         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21394                 $tdir/striped/. ; do
21395                 FILESET="$fileset/$dir" mount_client $submount ||
21396                         error "mount $dir failed"
21397                 umount_client $submount
21398         done
21399
21400         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21401         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21402                 error "mount $tdir/remote failed"
21403 }
21404 run_test 247f "mount striped or remote directory as fileset"
21405
21406 test_247g() {
21407         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21408         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21409                 skip "Need at least version 2.14.50"
21410
21411         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21412                 error "mkdir $tdir failed"
21413         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21414
21415         local submount=${MOUNT}_$tdir
21416
21417         mkdir -p $submount || error "mkdir $submount failed"
21418         stack_trap "rmdir $submount"
21419
21420         FILESET="$fileset/$tdir" mount_client $submount ||
21421                 error "mount $dir failed"
21422         stack_trap "umount $submount"
21423
21424         local mdts=$(comma_list $(mdts_nodes))
21425
21426         local nrpcs
21427
21428         stat $submount > /dev/null
21429         cancel_lru_locks $MDC
21430         stat $submount > /dev/null
21431         stat $submount/$tfile > /dev/null
21432         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21433         stat $submount/$tfile > /dev/null
21434         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21435                 awk '/getattr/ {sum += $2} END {print sum}')
21436
21437         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21438 }
21439 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21440
21441 test_248a() {
21442         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21443         [ -z "$fast_read_sav" ] && skip "no fast read support"
21444
21445         # create a large file for fast read verification
21446         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21447
21448         # make sure the file is created correctly
21449         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21450                 { rm -f $DIR/$tfile; skip "file creation error"; }
21451
21452         echo "Test 1: verify that fast read is 4 times faster on cache read"
21453
21454         # small read with fast read enabled
21455         $LCTL set_param -n llite.*.fast_read=1
21456         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21457                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21458                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21459         # small read with fast read disabled
21460         $LCTL set_param -n llite.*.fast_read=0
21461         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21462                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21463                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21464
21465         # verify that fast read is 4 times faster for cache read
21466         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21467                 error_not_in_vm "fast read was not 4 times faster: " \
21468                            "$t_fast vs $t_slow"
21469
21470         echo "Test 2: verify the performance between big and small read"
21471         $LCTL set_param -n llite.*.fast_read=1
21472
21473         # 1k non-cache read
21474         cancel_lru_locks osc
21475         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21476                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21477                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21478
21479         # 1M non-cache read
21480         cancel_lru_locks osc
21481         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21482                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21483                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21484
21485         # verify that big IO is not 4 times faster than small IO
21486         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21487                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21488
21489         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21490         rm -f $DIR/$tfile
21491 }
21492 run_test 248a "fast read verification"
21493
21494 test_248b() {
21495         # Default short_io_bytes=16384, try both smaller and larger sizes.
21496         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21497         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21498         echo "bs=53248 count=113 normal buffered write"
21499         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21500                 error "dd of initial data file failed"
21501         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21502
21503         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21504         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21505                 error "dd with sync normal writes failed"
21506         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21507
21508         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21509         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21510                 error "dd with sync small writes failed"
21511         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21512
21513         cancel_lru_locks osc
21514
21515         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21516         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21517         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21518         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21519                 iflag=direct || error "dd with O_DIRECT small read failed"
21520         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21521         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21522                 error "compare $TMP/$tfile.1 failed"
21523
21524         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21525         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21526
21527         # just to see what the maximum tunable value is, and test parsing
21528         echo "test invalid parameter 2MB"
21529         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21530                 error "too-large short_io_bytes allowed"
21531         echo "test maximum parameter 512KB"
21532         # if we can set a larger short_io_bytes, run test regardless of version
21533         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21534                 # older clients may not allow setting it this large, that's OK
21535                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21536                         skip "Need at least client version 2.13.50"
21537                 error "medium short_io_bytes failed"
21538         fi
21539         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21540         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21541
21542         echo "test large parameter 64KB"
21543         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21544         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21545
21546         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21547         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21548                 error "dd with sync large writes failed"
21549         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21550
21551         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21552         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21553         num=$((113 * 4096 / PAGE_SIZE))
21554         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21555         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21556                 error "dd with O_DIRECT large writes failed"
21557         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21558                 error "compare $DIR/$tfile.3 failed"
21559
21560         cancel_lru_locks osc
21561
21562         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21563         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21564                 error "dd with O_DIRECT large read failed"
21565         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21566                 error "compare $TMP/$tfile.2 failed"
21567
21568         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21569         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21570                 error "dd with O_DIRECT large read failed"
21571         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21572                 error "compare $TMP/$tfile.3 failed"
21573 }
21574 run_test 248b "test short_io read and write for both small and large sizes"
21575
21576 test_249() { # LU-7890
21577         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21578                 skip "Need at least version 2.8.54"
21579
21580         rm -f $DIR/$tfile
21581         $LFS setstripe -c 1 $DIR/$tfile
21582         # Offset 2T == 4k * 512M
21583         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21584                 error "dd to 2T offset failed"
21585 }
21586 run_test 249 "Write above 2T file size"
21587
21588 test_250() {
21589         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21590          && skip "no 16TB file size limit on ZFS"
21591
21592         $LFS setstripe -c 1 $DIR/$tfile
21593         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21594         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21595         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21596         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21597                 conv=notrunc,fsync && error "append succeeded"
21598         return 0
21599 }
21600 run_test 250 "Write above 16T limit"
21601
21602 test_251() {
21603         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21604
21605         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21606         #Skip once - writing the first stripe will succeed
21607         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21608         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21609                 error "short write happened"
21610
21611         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21612         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21613                 error "short read happened"
21614
21615         rm -f $DIR/$tfile
21616 }
21617 run_test 251 "Handling short read and write correctly"
21618
21619 test_252() {
21620         remote_mds_nodsh && skip "remote MDS with nodsh"
21621         remote_ost_nodsh && skip "remote OST with nodsh"
21622         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21623                 skip_env "ldiskfs only test"
21624         fi
21625
21626         local tgt
21627         local dev
21628         local out
21629         local uuid
21630         local num
21631         local gen
21632
21633         # check lr_reader on OST0000
21634         tgt=ost1
21635         dev=$(facet_device $tgt)
21636         out=$(do_facet $tgt $LR_READER $dev)
21637         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21638         echo "$out"
21639         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21640         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21641                 error "Invalid uuid returned by $LR_READER on target $tgt"
21642         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21643
21644         # check lr_reader -c on MDT0000
21645         tgt=mds1
21646         dev=$(facet_device $tgt)
21647         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21648                 skip "$LR_READER does not support additional options"
21649         fi
21650         out=$(do_facet $tgt $LR_READER -c $dev)
21651         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21652         echo "$out"
21653         num=$(echo "$out" | grep -c "mdtlov")
21654         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21655                 error "Invalid number of mdtlov clients returned by $LR_READER"
21656         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21657
21658         # check lr_reader -cr on MDT0000
21659         out=$(do_facet $tgt $LR_READER -cr $dev)
21660         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21661         echo "$out"
21662         echo "$out" | grep -q "^reply_data:$" ||
21663                 error "$LR_READER should have returned 'reply_data' section"
21664         num=$(echo "$out" | grep -c "client_generation")
21665         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21666 }
21667 run_test 252 "check lr_reader tool"
21668
21669 test_253() {
21670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21671         remote_mds_nodsh && skip "remote MDS with nodsh"
21672         remote_mgs_nodsh && skip "remote MGS with nodsh"
21673
21674         local ostidx=0
21675         local rc=0
21676         local ost_name=$(ostname_from_index $ostidx)
21677
21678         # on the mdt's osc
21679         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21680         do_facet $SINGLEMDS $LCTL get_param -n \
21681                 osp.$mdtosc_proc1.reserved_mb_high ||
21682                 skip  "remote MDS does not support reserved_mb_high"
21683
21684         rm -rf $DIR/$tdir
21685         wait_mds_ost_sync
21686         wait_delete_completed
21687         mkdir $DIR/$tdir
21688
21689         pool_add $TESTNAME || error "Pool creation failed"
21690         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21691
21692         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21693                 error "Setstripe failed"
21694
21695         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21696
21697         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21698                     grep "watermarks")
21699         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21700
21701         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21702                         osp.$mdtosc_proc1.prealloc_status)
21703         echo "prealloc_status $oa_status"
21704
21705         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21706                 error "File creation should fail"
21707
21708         #object allocation was stopped, but we still able to append files
21709         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21710                 oflag=append || error "Append failed"
21711
21712         rm -f $DIR/$tdir/$tfile.0
21713
21714         # For this test, we want to delete the files we created to go out of
21715         # space but leave the watermark, so we remain nearly out of space
21716         ost_watermarks_enospc_delete_files $tfile $ostidx
21717
21718         wait_delete_completed
21719
21720         sleep_maxage
21721
21722         for i in $(seq 10 12); do
21723                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21724                         2>/dev/null || error "File creation failed after rm"
21725         done
21726
21727         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21728                         osp.$mdtosc_proc1.prealloc_status)
21729         echo "prealloc_status $oa_status"
21730
21731         if (( oa_status != 0 )); then
21732                 error "Object allocation still disable after rm"
21733         fi
21734 }
21735 run_test 253 "Check object allocation limit"
21736
21737 test_254() {
21738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21739         remote_mds_nodsh && skip "remote MDS with nodsh"
21740
21741         local mdt=$(facet_svc $SINGLEMDS)
21742
21743         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21744                 skip "MDS does not support changelog_size"
21745
21746         local cl_user
21747
21748         changelog_register || error "changelog_register failed"
21749
21750         changelog_clear 0 || error "changelog_clear failed"
21751
21752         local size1=$(do_facet $SINGLEMDS \
21753                       $LCTL get_param -n mdd.$mdt.changelog_size)
21754         echo "Changelog size $size1"
21755
21756         rm -rf $DIR/$tdir
21757         $LFS mkdir -i 0 $DIR/$tdir
21758         # change something
21759         mkdir -p $DIR/$tdir/pics/2008/zachy
21760         touch $DIR/$tdir/pics/2008/zachy/timestamp
21761         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21762         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21763         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21764         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21765         rm $DIR/$tdir/pics/desktop.jpg
21766
21767         local size2=$(do_facet $SINGLEMDS \
21768                       $LCTL get_param -n mdd.$mdt.changelog_size)
21769         echo "Changelog size after work $size2"
21770
21771         (( $size2 > $size1 )) ||
21772                 error "new Changelog size=$size2 less than old size=$size1"
21773 }
21774 run_test 254 "Check changelog size"
21775
21776 ladvise_no_type()
21777 {
21778         local type=$1
21779         local file=$2
21780
21781         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21782                 awk -F: '{print $2}' | grep $type > /dev/null
21783         if [ $? -ne 0 ]; then
21784                 return 0
21785         fi
21786         return 1
21787 }
21788
21789 ladvise_no_ioctl()
21790 {
21791         local file=$1
21792
21793         lfs ladvise -a willread $file > /dev/null 2>&1
21794         if [ $? -eq 0 ]; then
21795                 return 1
21796         fi
21797
21798         lfs ladvise -a willread $file 2>&1 |
21799                 grep "Inappropriate ioctl for device" > /dev/null
21800         if [ $? -eq 0 ]; then
21801                 return 0
21802         fi
21803         return 1
21804 }
21805
21806 percent() {
21807         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21808 }
21809
21810 # run a random read IO workload
21811 # usage: random_read_iops <filename> <filesize> <iosize>
21812 random_read_iops() {
21813         local file=$1
21814         local fsize=$2
21815         local iosize=${3:-4096}
21816
21817         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21818                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21819 }
21820
21821 drop_file_oss_cache() {
21822         local file="$1"
21823         local nodes="$2"
21824
21825         $LFS ladvise -a dontneed $file 2>/dev/null ||
21826                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21827 }
21828
21829 ladvise_willread_performance()
21830 {
21831         local repeat=10
21832         local average_origin=0
21833         local average_cache=0
21834         local average_ladvise=0
21835
21836         for ((i = 1; i <= $repeat; i++)); do
21837                 echo "Iter $i/$repeat: reading without willread hint"
21838                 cancel_lru_locks osc
21839                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21840                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21841                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21842                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21843
21844                 cancel_lru_locks osc
21845                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21846                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21847                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21848
21849                 cancel_lru_locks osc
21850                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21851                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21852                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21853                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21854                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21855         done
21856         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21857         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21858         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21859
21860         speedup_cache=$(percent $average_cache $average_origin)
21861         speedup_ladvise=$(percent $average_ladvise $average_origin)
21862
21863         echo "Average uncached read: $average_origin"
21864         echo "Average speedup with OSS cached read: " \
21865                 "$average_cache = +$speedup_cache%"
21866         echo "Average speedup with ladvise willread: " \
21867                 "$average_ladvise = +$speedup_ladvise%"
21868
21869         local lowest_speedup=20
21870         if (( ${average_cache%.*} < $lowest_speedup )); then
21871                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21872                      " got $average_cache%. Skipping ladvise willread check."
21873                 return 0
21874         fi
21875
21876         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21877         # it is still good to run until then to exercise 'ladvise willread'
21878         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21879                 [ "$ost1_FSTYPE" = "zfs" ] &&
21880                 echo "osd-zfs does not support dontneed or drop_caches" &&
21881                 return 0
21882
21883         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21884         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21885                 error_not_in_vm "Speedup with willread is less than " \
21886                         "$lowest_speedup%, got $average_ladvise%"
21887 }
21888
21889 test_255a() {
21890         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21891                 skip "lustre < 2.8.54 does not support ladvise "
21892         remote_ost_nodsh && skip "remote OST with nodsh"
21893
21894         stack_trap "rm -f $DIR/$tfile"
21895         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21896
21897         ladvise_no_type willread $DIR/$tfile &&
21898                 skip "willread ladvise is not supported"
21899
21900         ladvise_no_ioctl $DIR/$tfile &&
21901                 skip "ladvise ioctl is not supported"
21902
21903         local size_mb=100
21904         local size=$((size_mb * 1048576))
21905         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21906                 error "dd to $DIR/$tfile failed"
21907
21908         lfs ladvise -a willread $DIR/$tfile ||
21909                 error "Ladvise failed with no range argument"
21910
21911         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21912                 error "Ladvise failed with no -l or -e argument"
21913
21914         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21915                 error "Ladvise failed with only -e argument"
21916
21917         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21918                 error "Ladvise failed with only -l argument"
21919
21920         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21921                 error "End offset should not be smaller than start offset"
21922
21923         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21924                 error "End offset should not be equal to start offset"
21925
21926         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21927                 error "Ladvise failed with overflowing -s argument"
21928
21929         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21930                 error "Ladvise failed with overflowing -e argument"
21931
21932         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21933                 error "Ladvise failed with overflowing -l argument"
21934
21935         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21936                 error "Ladvise succeeded with conflicting -l and -e arguments"
21937
21938         echo "Synchronous ladvise should wait"
21939         local delay=4
21940 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21941         do_nodes $(comma_list $(osts_nodes)) \
21942                 $LCTL set_param fail_val=$delay fail_loc=0x237
21943
21944         local start_ts=$SECONDS
21945         lfs ladvise -a willread $DIR/$tfile ||
21946                 error "Ladvise failed with no range argument"
21947         local end_ts=$SECONDS
21948         local inteval_ts=$((end_ts - start_ts))
21949
21950         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21951                 error "Synchronous advice didn't wait reply"
21952         fi
21953
21954         echo "Asynchronous ladvise shouldn't wait"
21955         local start_ts=$SECONDS
21956         lfs ladvise -a willread -b $DIR/$tfile ||
21957                 error "Ladvise failed with no range argument"
21958         local end_ts=$SECONDS
21959         local inteval_ts=$((end_ts - start_ts))
21960
21961         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21962                 error "Asynchronous advice blocked"
21963         fi
21964
21965         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21966         ladvise_willread_performance
21967 }
21968 run_test 255a "check 'lfs ladvise -a willread'"
21969
21970 facet_meminfo() {
21971         local facet=$1
21972         local info=$2
21973
21974         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21975 }
21976
21977 test_255b() {
21978         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21979                 skip "lustre < 2.8.54 does not support ladvise "
21980         remote_ost_nodsh && skip "remote OST with nodsh"
21981
21982         stack_trap "rm -f $DIR/$tfile"
21983         lfs setstripe -c 1 -i 0 $DIR/$tfile
21984
21985         ladvise_no_type dontneed $DIR/$tfile &&
21986                 skip "dontneed ladvise is not supported"
21987
21988         ladvise_no_ioctl $DIR/$tfile &&
21989                 skip "ladvise ioctl is not supported"
21990
21991         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21992                 [ "$ost1_FSTYPE" = "zfs" ] &&
21993                 skip "zfs-osd does not support 'ladvise dontneed'"
21994
21995         local size_mb=100
21996         local size=$((size_mb * 1048576))
21997         # In order to prevent disturbance of other processes, only check 3/4
21998         # of the memory usage
21999         local kibibytes=$((size_mb * 1024 * 3 / 4))
22000
22001         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22002                 error "dd to $DIR/$tfile failed"
22003
22004         #force write to complete before dropping OST cache & checking memory
22005         sync
22006
22007         local total=$(facet_meminfo ost1 MemTotal)
22008         echo "Total memory: $total KiB"
22009
22010         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22011         local before_read=$(facet_meminfo ost1 Cached)
22012         echo "Cache used before read: $before_read KiB"
22013
22014         lfs ladvise -a willread $DIR/$tfile ||
22015                 error "Ladvise willread failed"
22016         local after_read=$(facet_meminfo ost1 Cached)
22017         echo "Cache used after read: $after_read KiB"
22018
22019         lfs ladvise -a dontneed $DIR/$tfile ||
22020                 error "Ladvise dontneed again failed"
22021         local no_read=$(facet_meminfo ost1 Cached)
22022         echo "Cache used after dontneed ladvise: $no_read KiB"
22023
22024         if [ $total -lt $((before_read + kibibytes)) ]; then
22025                 echo "Memory is too small, abort checking"
22026                 return 0
22027         fi
22028
22029         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22030                 error "Ladvise willread should use more memory" \
22031                         "than $kibibytes KiB"
22032         fi
22033
22034         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22035                 error "Ladvise dontneed should release more memory" \
22036                         "than $kibibytes KiB"
22037         fi
22038 }
22039 run_test 255b "check 'lfs ladvise -a dontneed'"
22040
22041 test_255c() {
22042         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22043                 skip "lustre < 2.10.50 does not support lockahead"
22044
22045         local ost1_imp=$(get_osc_import_name client ost1)
22046         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22047                          cut -d'.' -f2)
22048         local count
22049         local new_count
22050         local difference
22051         local i
22052         local rc
22053
22054         test_mkdir -p $DIR/$tdir
22055         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22056
22057         #test 10 returns only success/failure
22058         i=10
22059         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22060         rc=$?
22061         if [ $rc -eq 255 ]; then
22062                 error "Ladvise test${i} failed, ${rc}"
22063         fi
22064
22065         #test 11 counts lock enqueue requests, all others count new locks
22066         i=11
22067         count=$(do_facet ost1 \
22068                 $LCTL get_param -n ost.OSS.ost.stats)
22069         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22070
22071         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22072         rc=$?
22073         if [ $rc -eq 255 ]; then
22074                 error "Ladvise test${i} failed, ${rc}"
22075         fi
22076
22077         new_count=$(do_facet ost1 \
22078                 $LCTL get_param -n ost.OSS.ost.stats)
22079         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22080                    awk '{ print $2 }')
22081
22082         difference="$((new_count - count))"
22083         if [ $difference -ne $rc ]; then
22084                 error "Ladvise test${i}, bad enqueue count, returned " \
22085                       "${rc}, actual ${difference}"
22086         fi
22087
22088         for i in $(seq 12 21); do
22089                 # If we do not do this, we run the risk of having too many
22090                 # locks and starting lock cancellation while we are checking
22091                 # lock counts.
22092                 cancel_lru_locks osc
22093
22094                 count=$($LCTL get_param -n \
22095                        ldlm.namespaces.$imp_name.lock_unused_count)
22096
22097                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22098                 rc=$?
22099                 if [ $rc -eq 255 ]; then
22100                         error "Ladvise test ${i} failed, ${rc}"
22101                 fi
22102
22103                 new_count=$($LCTL get_param -n \
22104                        ldlm.namespaces.$imp_name.lock_unused_count)
22105                 difference="$((new_count - count))"
22106
22107                 # Test 15 output is divided by 100 to map down to valid return
22108                 if [ $i -eq 15 ]; then
22109                         rc="$((rc * 100))"
22110                 fi
22111
22112                 if [ $difference -ne $rc ]; then
22113                         error "Ladvise test ${i}, bad lock count, returned " \
22114                               "${rc}, actual ${difference}"
22115                 fi
22116         done
22117
22118         #test 22 returns only success/failure
22119         i=22
22120         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22121         rc=$?
22122         if [ $rc -eq 255 ]; then
22123                 error "Ladvise test${i} failed, ${rc}"
22124         fi
22125 }
22126 run_test 255c "suite of ladvise lockahead tests"
22127
22128 test_256() {
22129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22130         remote_mds_nodsh && skip "remote MDS with nodsh"
22131         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22132         changelog_users $SINGLEMDS | grep "^cl" &&
22133                 skip "active changelog user"
22134
22135         local cl_user
22136         local cat_sl
22137         local mdt_dev
22138
22139         mdt_dev=$(facet_device $SINGLEMDS)
22140         echo $mdt_dev
22141
22142         changelog_register || error "changelog_register failed"
22143
22144         rm -rf $DIR/$tdir
22145         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22146
22147         changelog_clear 0 || error "changelog_clear failed"
22148
22149         # change something
22150         touch $DIR/$tdir/{1..10}
22151
22152         # stop the MDT
22153         stop $SINGLEMDS || error "Fail to stop MDT"
22154
22155         # remount the MDT
22156         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22157                 error "Fail to start MDT"
22158
22159         #after mount new plainllog is used
22160         touch $DIR/$tdir/{11..19}
22161         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22162         stack_trap "rm -f $tmpfile"
22163         cat_sl=$(do_facet $SINGLEMDS "sync; \
22164                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22165                  llog_reader $tmpfile | grep -c type=1064553b")
22166         do_facet $SINGLEMDS llog_reader $tmpfile
22167
22168         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22169
22170         changelog_clear 0 || error "changelog_clear failed"
22171
22172         cat_sl=$(do_facet $SINGLEMDS "sync; \
22173                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22174                  llog_reader $tmpfile | grep -c type=1064553b")
22175
22176         if (( cat_sl == 2 )); then
22177                 error "Empty plain llog was not deleted from changelog catalog"
22178         elif (( cat_sl != 1 )); then
22179                 error "Active plain llog shouldn't be deleted from catalog"
22180         fi
22181 }
22182 run_test 256 "Check llog delete for empty and not full state"
22183
22184 test_257() {
22185         remote_mds_nodsh && skip "remote MDS with nodsh"
22186         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22187                 skip "Need MDS version at least 2.8.55"
22188
22189         test_mkdir $DIR/$tdir
22190
22191         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22192                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22193         stat $DIR/$tdir
22194
22195 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22196         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22197         local facet=mds$((mdtidx + 1))
22198         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22199         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22200
22201         stop $facet || error "stop MDS failed"
22202         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22203                 error "start MDS fail"
22204         wait_recovery_complete $facet
22205 }
22206 run_test 257 "xattr locks are not lost"
22207
22208 # Verify we take the i_mutex when security requires it
22209 test_258a() {
22210 #define OBD_FAIL_IMUTEX_SEC 0x141c
22211         $LCTL set_param fail_loc=0x141c
22212         touch $DIR/$tfile
22213         chmod u+s $DIR/$tfile
22214         chmod a+rwx $DIR/$tfile
22215         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22216         RC=$?
22217         if [ $RC -ne 0 ]; then
22218                 error "error, failed to take i_mutex, rc=$?"
22219         fi
22220         rm -f $DIR/$tfile
22221 }
22222 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22223
22224 # Verify we do NOT take the i_mutex in the normal case
22225 test_258b() {
22226 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22227         $LCTL set_param fail_loc=0x141d
22228         touch $DIR/$tfile
22229         chmod a+rwx $DIR
22230         chmod a+rw $DIR/$tfile
22231         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22232         RC=$?
22233         if [ $RC -ne 0 ]; then
22234                 error "error, took i_mutex unnecessarily, rc=$?"
22235         fi
22236         rm -f $DIR/$tfile
22237
22238 }
22239 run_test 258b "verify i_mutex security behavior"
22240
22241 test_259() {
22242         local file=$DIR/$tfile
22243         local before
22244         local after
22245
22246         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22247
22248         stack_trap "rm -f $file" EXIT
22249
22250         wait_delete_completed
22251         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22252         echo "before: $before"
22253
22254         $LFS setstripe -i 0 -c 1 $file
22255         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22256         sync_all_data
22257         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22258         echo "after write: $after"
22259
22260 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22261         do_facet ost1 $LCTL set_param fail_loc=0x2301
22262         $TRUNCATE $file 0
22263         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22264         echo "after truncate: $after"
22265
22266         stop ost1
22267         do_facet ost1 $LCTL set_param fail_loc=0
22268         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22269         sleep 2
22270         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22271         echo "after restart: $after"
22272         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22273                 error "missing truncate?"
22274
22275         return 0
22276 }
22277 run_test 259 "crash at delayed truncate"
22278
22279 test_260() {
22280 #define OBD_FAIL_MDC_CLOSE               0x806
22281         $LCTL set_param fail_loc=0x80000806
22282         touch $DIR/$tfile
22283
22284 }
22285 run_test 260 "Check mdc_close fail"
22286
22287 ### Data-on-MDT sanity tests ###
22288 test_270a() {
22289         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22290                 skip "Need MDS version at least 2.10.55 for DoM"
22291
22292         # create DoM file
22293         local dom=$DIR/$tdir/dom_file
22294         local tmp=$DIR/$tdir/tmp_file
22295
22296         mkdir_on_mdt0 $DIR/$tdir
22297
22298         # basic checks for DoM component creation
22299         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22300                 error "Can set MDT layout to non-first entry"
22301
22302         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22303                 error "Can define multiple entries as MDT layout"
22304
22305         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22306
22307         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22308         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22309         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22310
22311         local mdtidx=$($LFS getstripe -m $dom)
22312         local mdtname=MDT$(printf %04x $mdtidx)
22313         local facet=mds$((mdtidx + 1))
22314         local space_check=1
22315
22316         # Skip free space checks with ZFS
22317         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22318
22319         # write
22320         sync
22321         local size_tmp=$((65536 * 3))
22322         local mdtfree1=$(do_facet $facet \
22323                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22324
22325         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22326         # check also direct IO along write
22327         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22328         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22329         sync
22330         cmp $tmp $dom || error "file data is different"
22331         [ $(stat -c%s $dom) == $size_tmp ] ||
22332                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22333         if [ $space_check == 1 ]; then
22334                 local mdtfree2=$(do_facet $facet \
22335                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22336
22337                 # increase in usage from by $size_tmp
22338                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22339                         error "MDT free space wrong after write: " \
22340                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22341         fi
22342
22343         # truncate
22344         local size_dom=10000
22345
22346         $TRUNCATE $dom $size_dom
22347         [ $(stat -c%s $dom) == $size_dom ] ||
22348                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22349         if [ $space_check == 1 ]; then
22350                 mdtfree1=$(do_facet $facet \
22351                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22352                 # decrease in usage from $size_tmp to new $size_dom
22353                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22354                   $(((size_tmp - size_dom) / 1024)) ] ||
22355                         error "MDT free space is wrong after truncate: " \
22356                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22357         fi
22358
22359         # append
22360         cat $tmp >> $dom
22361         sync
22362         size_dom=$((size_dom + size_tmp))
22363         [ $(stat -c%s $dom) == $size_dom ] ||
22364                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22365         if [ $space_check == 1 ]; then
22366                 mdtfree2=$(do_facet $facet \
22367                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22368                 # increase in usage by $size_tmp from previous
22369                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22370                         error "MDT free space is wrong after append: " \
22371                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22372         fi
22373
22374         # delete
22375         rm $dom
22376         if [ $space_check == 1 ]; then
22377                 mdtfree1=$(do_facet $facet \
22378                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22379                 # decrease in usage by $size_dom from previous
22380                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22381                         error "MDT free space is wrong after removal: " \
22382                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22383         fi
22384
22385         # combined striping
22386         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22387                 error "Can't create DoM + OST striping"
22388
22389         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22390         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22391         # check also direct IO along write
22392         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22393         sync
22394         cmp $tmp $dom || error "file data is different"
22395         [ $(stat -c%s $dom) == $size_tmp ] ||
22396                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22397         rm $dom $tmp
22398
22399         return 0
22400 }
22401 run_test 270a "DoM: basic functionality tests"
22402
22403 test_270b() {
22404         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22405                 skip "Need MDS version at least 2.10.55"
22406
22407         local dom=$DIR/$tdir/dom_file
22408         local max_size=1048576
22409
22410         mkdir -p $DIR/$tdir
22411         $LFS setstripe -E $max_size -L mdt $dom
22412
22413         # truncate over the limit
22414         $TRUNCATE $dom $(($max_size + 1)) &&
22415                 error "successful truncate over the maximum size"
22416         # write over the limit
22417         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22418                 error "successful write over the maximum size"
22419         # append over the limit
22420         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22421         echo "12345" >> $dom && error "successful append over the maximum size"
22422         rm $dom
22423
22424         return 0
22425 }
22426 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22427
22428 test_270c() {
22429         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22430                 skip "Need MDS version at least 2.10.55"
22431
22432         mkdir -p $DIR/$tdir
22433         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22434
22435         # check files inherit DoM EA
22436         touch $DIR/$tdir/first
22437         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22438                 error "bad pattern"
22439         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22440                 error "bad stripe count"
22441         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22442                 error "bad stripe size"
22443
22444         # check directory inherits DoM EA and uses it as default
22445         mkdir $DIR/$tdir/subdir
22446         touch $DIR/$tdir/subdir/second
22447         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22448                 error "bad pattern in sub-directory"
22449         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22450                 error "bad stripe count in sub-directory"
22451         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22452                 error "bad stripe size in sub-directory"
22453         return 0
22454 }
22455 run_test 270c "DoM: DoM EA inheritance tests"
22456
22457 test_270d() {
22458         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22459                 skip "Need MDS version at least 2.10.55"
22460
22461         mkdir -p $DIR/$tdir
22462         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22463
22464         # inherit default DoM striping
22465         mkdir $DIR/$tdir/subdir
22466         touch $DIR/$tdir/subdir/f1
22467
22468         # change default directory striping
22469         $LFS setstripe -c 1 $DIR/$tdir/subdir
22470         touch $DIR/$tdir/subdir/f2
22471         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22472                 error "wrong default striping in file 2"
22473         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22474                 error "bad pattern in file 2"
22475         return 0
22476 }
22477 run_test 270d "DoM: change striping from DoM to RAID0"
22478
22479 test_270e() {
22480         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22481                 skip "Need MDS version at least 2.10.55"
22482
22483         mkdir -p $DIR/$tdir/dom
22484         mkdir -p $DIR/$tdir/norm
22485         DOMFILES=20
22486         NORMFILES=10
22487         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22488         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22489
22490         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22491         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22492
22493         # find DoM files by layout
22494         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22495         [ $NUM -eq  $DOMFILES ] ||
22496                 error "lfs find -L: found $NUM, expected $DOMFILES"
22497         echo "Test 1: lfs find 20 DOM files by layout: OK"
22498
22499         # there should be 1 dir with default DOM striping
22500         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22501         [ $NUM -eq  1 ] ||
22502                 error "lfs find -L: found $NUM, expected 1 dir"
22503         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22504
22505         # find DoM files by stripe size
22506         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22507         [ $NUM -eq  $DOMFILES ] ||
22508                 error "lfs find -S: found $NUM, expected $DOMFILES"
22509         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22510
22511         # find files by stripe offset except DoM files
22512         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22513         [ $NUM -eq  $NORMFILES ] ||
22514                 error "lfs find -i: found $NUM, expected $NORMFILES"
22515         echo "Test 5: lfs find no DOM files by stripe index: OK"
22516         return 0
22517 }
22518 run_test 270e "DoM: lfs find with DoM files test"
22519
22520 test_270f() {
22521         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22522                 skip "Need MDS version at least 2.10.55"
22523
22524         local mdtname=${FSNAME}-MDT0000-mdtlov
22525         local dom=$DIR/$tdir/dom_file
22526         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22527                                                 lod.$mdtname.dom_stripesize)
22528         local dom_limit=131072
22529
22530         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22531         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22532                                                 lod.$mdtname.dom_stripesize)
22533         [ ${dom_limit} -eq ${dom_current} ] ||
22534                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22535
22536         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22537         $LFS setstripe -d $DIR/$tdir
22538         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22539                 error "Can't set directory default striping"
22540
22541         # exceed maximum stripe size
22542         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22543                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22544         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22545                 error "Able to create DoM component size more than LOD limit"
22546
22547         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22548         dom_current=$(do_facet mds1 $LCTL get_param -n \
22549                                                 lod.$mdtname.dom_stripesize)
22550         [ 0 -eq ${dom_current} ] ||
22551                 error "Can't set zero DoM stripe limit"
22552         rm $dom
22553
22554         # attempt to create DoM file on server with disabled DoM should
22555         # remove DoM entry from layout and be succeed
22556         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22557                 error "Can't create DoM file (DoM is disabled)"
22558         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22559                 error "File has DoM component while DoM is disabled"
22560         rm $dom
22561
22562         # attempt to create DoM file with only DoM stripe should return error
22563         $LFS setstripe -E $dom_limit -L mdt $dom &&
22564                 error "Able to create DoM-only file while DoM is disabled"
22565
22566         # too low values to be aligned with smallest stripe size 64K
22567         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22568         dom_current=$(do_facet mds1 $LCTL get_param -n \
22569                                                 lod.$mdtname.dom_stripesize)
22570         [ 30000 -eq ${dom_current} ] &&
22571                 error "Can set too small DoM stripe limit"
22572
22573         # 64K is a minimal stripe size in Lustre, expect limit of that size
22574         [ 65536 -eq ${dom_current} ] ||
22575                 error "Limit is not set to 64K but ${dom_current}"
22576
22577         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22578         dom_current=$(do_facet mds1 $LCTL get_param -n \
22579                                                 lod.$mdtname.dom_stripesize)
22580         echo $dom_current
22581         [ 2147483648 -eq ${dom_current} ] &&
22582                 error "Can set too large DoM stripe limit"
22583
22584         do_facet mds1 $LCTL set_param -n \
22585                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22586         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22587                 error "Can't create DoM component size after limit change"
22588         do_facet mds1 $LCTL set_param -n \
22589                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22590         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22591                 error "Can't create DoM file after limit decrease"
22592         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22593                 error "Can create big DoM component after limit decrease"
22594         touch ${dom}_def ||
22595                 error "Can't create file with old default layout"
22596
22597         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22598         return 0
22599 }
22600 run_test 270f "DoM: maximum DoM stripe size checks"
22601
22602 test_270g() {
22603         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22604                 skip "Need MDS version at least 2.13.52"
22605         local dom=$DIR/$tdir/$tfile
22606
22607         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22608         local lodname=${FSNAME}-MDT0000-mdtlov
22609
22610         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22611         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22612         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22613         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22614
22615         local dom_limit=1024
22616         local dom_threshold="50%"
22617
22618         $LFS setstripe -d $DIR/$tdir
22619         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22620                 error "Can't set directory default striping"
22621
22622         do_facet mds1 $LCTL set_param -n \
22623                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22624         # set 0 threshold and create DOM file to change tunable stripesize
22625         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22626         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22627                 error "Failed to create $dom file"
22628         # now tunable dom_cur_stripesize should reach maximum
22629         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22630                                         lod.${lodname}.dom_stripesize_cur_kb)
22631         [[ $dom_current == $dom_limit ]] ||
22632                 error "Current DOM stripesize is not maximum"
22633         rm $dom
22634
22635         # set threshold for further tests
22636         do_facet mds1 $LCTL set_param -n \
22637                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22638         echo "DOM threshold is $dom_threshold free space"
22639         local dom_def
22640         local dom_set
22641         # Spoof bfree to exceed threshold
22642         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22643         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22644         for spfree in 40 20 0 15 30 55; do
22645                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22646                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22647                         error "Failed to create $dom file"
22648                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22649                                         lod.${lodname}.dom_stripesize_cur_kb)
22650                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22651                 [[ $dom_def != $dom_current ]] ||
22652                         error "Default stripe size was not changed"
22653                 if (( spfree > 0 )) ; then
22654                         dom_set=$($LFS getstripe -S $dom)
22655                         (( dom_set == dom_def * 1024 )) ||
22656                                 error "DOM component size is still old"
22657                 else
22658                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22659                                 error "DoM component is set with no free space"
22660                 fi
22661                 rm $dom
22662                 dom_current=$dom_def
22663         done
22664 }
22665 run_test 270g "DoM: default DoM stripe size depends on free space"
22666
22667 test_270h() {
22668         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22669                 skip "Need MDS version at least 2.13.53"
22670
22671         local mdtname=${FSNAME}-MDT0000-mdtlov
22672         local dom=$DIR/$tdir/$tfile
22673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22674
22675         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22676         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22677
22678         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22679         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22680                 error "can't create OST file"
22681         # mirrored file with DOM entry in the second mirror
22682         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22683                 error "can't create mirror with DoM component"
22684
22685         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22686
22687         # DOM component in the middle and has other enries in the same mirror,
22688         # should succeed but lost DoM component
22689         $LFS setstripe --copy=${dom}_1 $dom ||
22690                 error "Can't create file from OST|DOM mirror layout"
22691         # check new file has no DoM layout after all
22692         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22693                 error "File has DoM component while DoM is disabled"
22694 }
22695 run_test 270h "DoM: DoM stripe removal when disabled on server"
22696
22697 test_270i() {
22698         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22699                 skip "Need MDS version at least 2.14.54"
22700
22701         mkdir $DIR/$tdir
22702         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22703                 error "setstripe should fail" || true
22704 }
22705 run_test 270i "DoM: setting invalid DoM striping should fail"
22706
22707 test_271a() {
22708         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22709                 skip "Need MDS version at least 2.10.55"
22710
22711         local dom=$DIR/$tdir/dom
22712
22713         mkdir -p $DIR/$tdir
22714
22715         $LFS setstripe -E 1024K -L mdt $dom
22716
22717         lctl set_param -n mdc.*.stats=clear
22718         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22719         cat $dom > /dev/null
22720         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22721         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22722         ls $dom
22723         rm -f $dom
22724 }
22725 run_test 271a "DoM: data is cached for read after write"
22726
22727 test_271b() {
22728         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22729                 skip "Need MDS version at least 2.10.55"
22730
22731         local dom=$DIR/$tdir/dom
22732
22733         mkdir -p $DIR/$tdir
22734
22735         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22736
22737         lctl set_param -n mdc.*.stats=clear
22738         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22739         cancel_lru_locks mdc
22740         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22741         # second stat to check size is cached on client
22742         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22743         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22744         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22745         rm -f $dom
22746 }
22747 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22748
22749 test_271ba() {
22750         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22751                 skip "Need MDS version at least 2.10.55"
22752
22753         local dom=$DIR/$tdir/dom
22754
22755         mkdir -p $DIR/$tdir
22756
22757         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22758
22759         lctl set_param -n mdc.*.stats=clear
22760         lctl set_param -n osc.*.stats=clear
22761         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22762         cancel_lru_locks mdc
22763         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22764         # second stat to check size is cached on client
22765         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22766         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22767         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22768         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22769         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22770         rm -f $dom
22771 }
22772 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22773
22774
22775 get_mdc_stats() {
22776         local mdtidx=$1
22777         local param=$2
22778         local mdt=MDT$(printf %04x $mdtidx)
22779
22780         if [ -z $param ]; then
22781                 lctl get_param -n mdc.*$mdt*.stats
22782         else
22783                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22784         fi
22785 }
22786
22787 test_271c() {
22788         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22789                 skip "Need MDS version at least 2.10.55"
22790
22791         local dom=$DIR/$tdir/dom
22792
22793         mkdir -p $DIR/$tdir
22794
22795         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22796
22797         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22798         local facet=mds$((mdtidx + 1))
22799
22800         cancel_lru_locks mdc
22801         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22802         createmany -o $dom 1000
22803         lctl set_param -n mdc.*.stats=clear
22804         smalliomany -w $dom 1000 200
22805         get_mdc_stats $mdtidx
22806         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22807         # Each file has 1 open, 1 IO enqueues, total 2000
22808         # but now we have also +1 getxattr for security.capability, total 3000
22809         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22810         unlinkmany $dom 1000
22811
22812         cancel_lru_locks mdc
22813         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22814         createmany -o $dom 1000
22815         lctl set_param -n mdc.*.stats=clear
22816         smalliomany -w $dom 1000 200
22817         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22818         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22819         # for OPEN and IO lock.
22820         [ $((enq - enq_2)) -ge 1000 ] ||
22821                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22822         unlinkmany $dom 1000
22823         return 0
22824 }
22825 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22826
22827 cleanup_271def_tests() {
22828         trap 0
22829         rm -f $1
22830 }
22831
22832 test_271d() {
22833         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22834                 skip "Need MDS version at least 2.10.57"
22835
22836         local dom=$DIR/$tdir/dom
22837         local tmp=$TMP/$tfile
22838         trap "cleanup_271def_tests $tmp" EXIT
22839
22840         mkdir -p $DIR/$tdir
22841
22842         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22843
22844         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22845
22846         cancel_lru_locks mdc
22847         dd if=/dev/urandom of=$tmp bs=1000 count=1
22848         dd if=$tmp of=$dom bs=1000 count=1
22849         cancel_lru_locks mdc
22850
22851         cat /etc/hosts >> $tmp
22852         lctl set_param -n mdc.*.stats=clear
22853
22854         # append data to the same file it should update local page
22855         echo "Append to the same page"
22856         cat /etc/hosts >> $dom
22857         local num=$(get_mdc_stats $mdtidx ost_read)
22858         local ra=$(get_mdc_stats $mdtidx req_active)
22859         local rw=$(get_mdc_stats $mdtidx req_waittime)
22860
22861         [ -z $num ] || error "$num READ RPC occured"
22862         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22863         echo "... DONE"
22864
22865         # compare content
22866         cmp $tmp $dom || error "file miscompare"
22867
22868         cancel_lru_locks mdc
22869         lctl set_param -n mdc.*.stats=clear
22870
22871         echo "Open and read file"
22872         cat $dom > /dev/null
22873         local num=$(get_mdc_stats $mdtidx ost_read)
22874         local ra=$(get_mdc_stats $mdtidx req_active)
22875         local rw=$(get_mdc_stats $mdtidx req_waittime)
22876
22877         [ -z $num ] || error "$num READ RPC occured"
22878         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22879         echo "... DONE"
22880
22881         # compare content
22882         cmp $tmp $dom || error "file miscompare"
22883
22884         return 0
22885 }
22886 run_test 271d "DoM: read on open (1K file in reply buffer)"
22887
22888 test_271f() {
22889         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22890                 skip "Need MDS version at least 2.10.57"
22891
22892         local dom=$DIR/$tdir/dom
22893         local tmp=$TMP/$tfile
22894         trap "cleanup_271def_tests $tmp" EXIT
22895
22896         mkdir -p $DIR/$tdir
22897
22898         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22899
22900         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22901
22902         cancel_lru_locks mdc
22903         dd if=/dev/urandom of=$tmp bs=265000 count=1
22904         dd if=$tmp of=$dom bs=265000 count=1
22905         cancel_lru_locks mdc
22906         cat /etc/hosts >> $tmp
22907         lctl set_param -n mdc.*.stats=clear
22908
22909         echo "Append to the same page"
22910         cat /etc/hosts >> $dom
22911         local num=$(get_mdc_stats $mdtidx ost_read)
22912         local ra=$(get_mdc_stats $mdtidx req_active)
22913         local rw=$(get_mdc_stats $mdtidx req_waittime)
22914
22915         [ -z $num ] || error "$num READ RPC occured"
22916         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22917         echo "... DONE"
22918
22919         # compare content
22920         cmp $tmp $dom || error "file miscompare"
22921
22922         cancel_lru_locks mdc
22923         lctl set_param -n mdc.*.stats=clear
22924
22925         echo "Open and read file"
22926         cat $dom > /dev/null
22927         local num=$(get_mdc_stats $mdtidx ost_read)
22928         local ra=$(get_mdc_stats $mdtidx req_active)
22929         local rw=$(get_mdc_stats $mdtidx req_waittime)
22930
22931         [ -z $num ] && num=0
22932         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22933         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22934         echo "... DONE"
22935
22936         # compare content
22937         cmp $tmp $dom || error "file miscompare"
22938
22939         return 0
22940 }
22941 run_test 271f "DoM: read on open (200K file and read tail)"
22942
22943 test_271g() {
22944         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22945                 skip "Skipping due to old client or server version"
22946
22947         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22948         # to get layout
22949         $CHECKSTAT -t file $DIR1/$tfile
22950
22951         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22952         MULTIOP_PID=$!
22953         sleep 1
22954         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22955         $LCTL set_param fail_loc=0x80000314
22956         rm $DIR1/$tfile || error "Unlink fails"
22957         RC=$?
22958         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22959         [ $RC -eq 0 ] || error "Failed write to stale object"
22960 }
22961 run_test 271g "Discard DoM data vs client flush race"
22962
22963 test_272a() {
22964         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22965                 skip "Need MDS version at least 2.11.50"
22966
22967         local dom=$DIR/$tdir/dom
22968         mkdir -p $DIR/$tdir
22969
22970         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22971         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22972                 error "failed to write data into $dom"
22973         local old_md5=$(md5sum $dom)
22974
22975         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22976                 error "failed to migrate to the same DoM component"
22977
22978         local new_md5=$(md5sum $dom)
22979
22980         [ "$old_md5" == "$new_md5" ] ||
22981                 error "md5sum differ: $old_md5, $new_md5"
22982
22983         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22984                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22985 }
22986 run_test 272a "DoM migration: new layout with the same DOM component"
22987
22988 test_272b() {
22989         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22990                 skip "Need MDS version at least 2.11.50"
22991
22992         local dom=$DIR/$tdir/dom
22993         mkdir -p $DIR/$tdir
22994         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22995
22996         local mdtidx=$($LFS getstripe -m $dom)
22997         local mdtname=MDT$(printf %04x $mdtidx)
22998         local facet=mds$((mdtidx + 1))
22999
23000         local mdtfree1=$(do_facet $facet \
23001                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23002         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23003                 error "failed to write data into $dom"
23004         local old_md5=$(md5sum $dom)
23005         cancel_lru_locks mdc
23006         local mdtfree1=$(do_facet $facet \
23007                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23008
23009         $LFS migrate -c2 $dom ||
23010                 error "failed to migrate to the new composite layout"
23011         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23012                 error "MDT stripe was not removed"
23013
23014         cancel_lru_locks mdc
23015         local new_md5=$(md5sum $dom)
23016         [ "$old_md5" == "$new_md5" ] ||
23017                 error "$old_md5 != $new_md5"
23018
23019         # Skip free space checks with ZFS
23020         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23021                 local mdtfree2=$(do_facet $facet \
23022                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23023                 [ $mdtfree2 -gt $mdtfree1 ] ||
23024                         error "MDT space is not freed after migration"
23025         fi
23026         return 0
23027 }
23028 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23029
23030 test_272c() {
23031         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23032                 skip "Need MDS version at least 2.11.50"
23033
23034         local dom=$DIR/$tdir/$tfile
23035         mkdir -p $DIR/$tdir
23036         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23037
23038         local mdtidx=$($LFS getstripe -m $dom)
23039         local mdtname=MDT$(printf %04x $mdtidx)
23040         local facet=mds$((mdtidx + 1))
23041
23042         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23043                 error "failed to write data into $dom"
23044         local old_md5=$(md5sum $dom)
23045         cancel_lru_locks mdc
23046         local mdtfree1=$(do_facet $facet \
23047                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23048
23049         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23050                 error "failed to migrate to the new composite layout"
23051         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23052                 error "MDT stripe was not removed"
23053
23054         cancel_lru_locks mdc
23055         local new_md5=$(md5sum $dom)
23056         [ "$old_md5" == "$new_md5" ] ||
23057                 error "$old_md5 != $new_md5"
23058
23059         # Skip free space checks with ZFS
23060         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23061                 local mdtfree2=$(do_facet $facet \
23062                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23063                 [ $mdtfree2 -gt $mdtfree1 ] ||
23064                         error "MDS space is not freed after migration"
23065         fi
23066         return 0
23067 }
23068 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23069
23070 test_272d() {
23071         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23072                 skip "Need MDS version at least 2.12.55"
23073
23074         local dom=$DIR/$tdir/$tfile
23075         mkdir -p $DIR/$tdir
23076         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23077
23078         local mdtidx=$($LFS getstripe -m $dom)
23079         local mdtname=MDT$(printf %04x $mdtidx)
23080         local facet=mds$((mdtidx + 1))
23081
23082         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23083                 error "failed to write data into $dom"
23084         local old_md5=$(md5sum $dom)
23085         cancel_lru_locks mdc
23086         local mdtfree1=$(do_facet $facet \
23087                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23088
23089         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23090                 error "failed mirroring to the new composite layout"
23091         $LFS mirror resync $dom ||
23092                 error "failed mirror resync"
23093         $LFS mirror split --mirror-id 1 -d $dom ||
23094                 error "failed mirror split"
23095
23096         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23097                 error "MDT stripe was not removed"
23098
23099         cancel_lru_locks mdc
23100         local new_md5=$(md5sum $dom)
23101         [ "$old_md5" == "$new_md5" ] ||
23102                 error "$old_md5 != $new_md5"
23103
23104         # Skip free space checks with ZFS
23105         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23106                 local mdtfree2=$(do_facet $facet \
23107                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23108                 [ $mdtfree2 -gt $mdtfree1 ] ||
23109                         error "MDS space is not freed after DOM mirror deletion"
23110         fi
23111         return 0
23112 }
23113 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23114
23115 test_272e() {
23116         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23117                 skip "Need MDS version at least 2.12.55"
23118
23119         local dom=$DIR/$tdir/$tfile
23120         mkdir -p $DIR/$tdir
23121         $LFS setstripe -c 2 $dom
23122
23123         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23124                 error "failed to write data into $dom"
23125         local old_md5=$(md5sum $dom)
23126         cancel_lru_locks
23127
23128         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23129                 error "failed mirroring to the DOM layout"
23130         $LFS mirror resync $dom ||
23131                 error "failed mirror resync"
23132         $LFS mirror split --mirror-id 1 -d $dom ||
23133                 error "failed mirror split"
23134
23135         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23136                 error "MDT stripe wasn't set"
23137
23138         cancel_lru_locks
23139         local new_md5=$(md5sum $dom)
23140         [ "$old_md5" == "$new_md5" ] ||
23141                 error "$old_md5 != $new_md5"
23142
23143         return 0
23144 }
23145 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23146
23147 test_272f() {
23148         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23149                 skip "Need MDS version at least 2.12.55"
23150
23151         local dom=$DIR/$tdir/$tfile
23152         mkdir -p $DIR/$tdir
23153         $LFS setstripe -c 2 $dom
23154
23155         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23156                 error "failed to write data into $dom"
23157         local old_md5=$(md5sum $dom)
23158         cancel_lru_locks
23159
23160         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23161                 error "failed migrating to the DOM file"
23162
23163         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23164                 error "MDT stripe wasn't set"
23165
23166         cancel_lru_locks
23167         local new_md5=$(md5sum $dom)
23168         [ "$old_md5" != "$new_md5" ] &&
23169                 error "$old_md5 != $new_md5"
23170
23171         return 0
23172 }
23173 run_test 272f "DoM migration: OST-striped file to DOM file"
23174
23175 test_273a() {
23176         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23177                 skip "Need MDS version at least 2.11.50"
23178
23179         # Layout swap cannot be done if either file has DOM component,
23180         # this will never be supported, migration should be used instead
23181
23182         local dom=$DIR/$tdir/$tfile
23183         mkdir -p $DIR/$tdir
23184
23185         $LFS setstripe -c2 ${dom}_plain
23186         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23187         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23188                 error "can swap layout with DoM component"
23189         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23190                 error "can swap layout with DoM component"
23191
23192         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23193         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23194                 error "can swap layout with DoM component"
23195         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23196                 error "can swap layout with DoM component"
23197         return 0
23198 }
23199 run_test 273a "DoM: layout swapping should fail with DOM"
23200
23201 test_273b() {
23202         mkdir -p $DIR/$tdir
23203         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23204
23205 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23206         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23207
23208         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23209 }
23210 run_test 273b "DoM: race writeback and object destroy"
23211
23212 test_275() {
23213         remote_ost_nodsh && skip "remote OST with nodsh"
23214         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23215                 skip "Need OST version >= 2.10.57"
23216
23217         local file=$DIR/$tfile
23218         local oss
23219
23220         oss=$(comma_list $(osts_nodes))
23221
23222         dd if=/dev/urandom of=$file bs=1M count=2 ||
23223                 error "failed to create a file"
23224         cancel_lru_locks osc
23225
23226         #lock 1
23227         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23228                 error "failed to read a file"
23229
23230 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23231         $LCTL set_param fail_loc=0x8000031f
23232
23233         cancel_lru_locks osc &
23234         sleep 1
23235
23236 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23237         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23238         #IO takes another lock, but matches the PENDING one
23239         #and places it to the IO RPC
23240         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23241                 error "failed to read a file with PENDING lock"
23242 }
23243 run_test 275 "Read on a canceled duplicate lock"
23244
23245 test_276() {
23246         remote_ost_nodsh && skip "remote OST with nodsh"
23247         local pid
23248
23249         do_facet ost1 "(while true; do \
23250                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23251                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23252         pid=$!
23253
23254         for LOOP in $(seq 20); do
23255                 stop ost1
23256                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23257         done
23258         kill -9 $pid
23259         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23260                 rm $TMP/sanity_276_pid"
23261 }
23262 run_test 276 "Race between mount and obd_statfs"
23263
23264 test_277() {
23265         $LCTL set_param ldlm.namespaces.*.lru_size=0
23266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23267         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23268                         grep ^used_mb | awk '{print $2}')
23269         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23270         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23271                 oflag=direct conv=notrunc
23272         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23273                         grep ^used_mb | awk '{print $2}')
23274         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23275 }
23276 run_test 277 "Direct IO shall drop page cache"
23277
23278 test_278() {
23279         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23280         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23281         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23282                 skip "needs the same host for mdt1 mdt2" && return
23283
23284         local pid1
23285         local pid2
23286
23287 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23288         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23289         stop mds2 &
23290         pid2=$!
23291
23292         stop mds1
23293
23294         echo "Starting MDTs"
23295         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23296         wait $pid2
23297 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23298 #will return NULL
23299         do_facet mds2 $LCTL set_param fail_loc=0
23300
23301         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23302         wait_recovery_complete mds2
23303 }
23304 run_test 278 "Race starting MDS between MDTs stop/start"
23305
23306 test_280() {
23307         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23308                 skip "Need MGS version at least 2.13.52"
23309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23310         combined_mgs_mds || skip "needs combined MGS/MDT"
23311
23312         umount_client $MOUNT
23313 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23314         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23315
23316         mount_client $MOUNT &
23317         sleep 1
23318         stop mgs || error "stop mgs failed"
23319         #for a race mgs would crash
23320         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23321         # make sure we unmount client before remounting
23322         wait
23323         umount_client $MOUNT
23324         mount_client $MOUNT || error "mount client failed"
23325 }
23326 run_test 280 "Race between MGS umount and client llog processing"
23327
23328 cleanup_test_300() {
23329         trap 0
23330         umask $SAVE_UMASK
23331 }
23332 test_striped_dir() {
23333         local mdt_index=$1
23334         local stripe_count
23335         local stripe_index
23336
23337         mkdir -p $DIR/$tdir
23338
23339         SAVE_UMASK=$(umask)
23340         trap cleanup_test_300 RETURN EXIT
23341
23342         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23343                                                 $DIR/$tdir/striped_dir ||
23344                 error "set striped dir error"
23345
23346         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23347         [ "$mode" = "755" ] || error "expect 755 got $mode"
23348
23349         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23350                 error "getdirstripe failed"
23351         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23352         if [ "$stripe_count" != "2" ]; then
23353                 error "1:stripe_count is $stripe_count, expect 2"
23354         fi
23355         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23356         if [ "$stripe_count" != "2" ]; then
23357                 error "2:stripe_count is $stripe_count, expect 2"
23358         fi
23359
23360         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23361         if [ "$stripe_index" != "$mdt_index" ]; then
23362                 error "stripe_index is $stripe_index, expect $mdt_index"
23363         fi
23364
23365         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23366                 error "nlink error after create striped dir"
23367
23368         mkdir $DIR/$tdir/striped_dir/a
23369         mkdir $DIR/$tdir/striped_dir/b
23370
23371         stat $DIR/$tdir/striped_dir/a ||
23372                 error "create dir under striped dir failed"
23373         stat $DIR/$tdir/striped_dir/b ||
23374                 error "create dir under striped dir failed"
23375
23376         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23377                 error "nlink error after mkdir"
23378
23379         rmdir $DIR/$tdir/striped_dir/a
23380         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23381                 error "nlink error after rmdir"
23382
23383         rmdir $DIR/$tdir/striped_dir/b
23384         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23385                 error "nlink error after rmdir"
23386
23387         chattr +i $DIR/$tdir/striped_dir
23388         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23389                 error "immutable flags not working under striped dir!"
23390         chattr -i $DIR/$tdir/striped_dir
23391
23392         rmdir $DIR/$tdir/striped_dir ||
23393                 error "rmdir striped dir error"
23394
23395         cleanup_test_300
23396
23397         true
23398 }
23399
23400 test_300a() {
23401         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23402                 skip "skipped for lustre < 2.7.0"
23403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23405
23406         test_striped_dir 0 || error "failed on striped dir on MDT0"
23407         test_striped_dir 1 || error "failed on striped dir on MDT0"
23408 }
23409 run_test 300a "basic striped dir sanity test"
23410
23411 test_300b() {
23412         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23413                 skip "skipped for lustre < 2.7.0"
23414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23416
23417         local i
23418         local mtime1
23419         local mtime2
23420         local mtime3
23421
23422         test_mkdir $DIR/$tdir || error "mkdir fail"
23423         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23424                 error "set striped dir error"
23425         for i in {0..9}; do
23426                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23427                 sleep 1
23428                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23429                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23430                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23431                 sleep 1
23432                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23433                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23434                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23435         done
23436         true
23437 }
23438 run_test 300b "check ctime/mtime for striped dir"
23439
23440 test_300c() {
23441         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23442                 skip "skipped for lustre < 2.7.0"
23443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23445
23446         local file_count
23447
23448         mkdir_on_mdt0 $DIR/$tdir
23449         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23450                 error "set striped dir error"
23451
23452         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23453                 error "chown striped dir failed"
23454
23455         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23456                 error "create 5k files failed"
23457
23458         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23459
23460         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23461
23462         rm -rf $DIR/$tdir
23463 }
23464 run_test 300c "chown && check ls under striped directory"
23465
23466 test_300d() {
23467         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23468                 skip "skipped for lustre < 2.7.0"
23469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23470         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23471
23472         local stripe_count
23473         local file
23474
23475         mkdir -p $DIR/$tdir
23476         $LFS setstripe -c 2 $DIR/$tdir
23477
23478         #local striped directory
23479         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23480                 error "set striped dir error"
23481         #look at the directories for debug purposes
23482         ls -l $DIR/$tdir
23483         $LFS getdirstripe $DIR/$tdir
23484         ls -l $DIR/$tdir/striped_dir
23485         $LFS getdirstripe $DIR/$tdir/striped_dir
23486         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23487                 error "create 10 files failed"
23488
23489         #remote striped directory
23490         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23491                 error "set striped dir error"
23492         #look at the directories for debug purposes
23493         ls -l $DIR/$tdir
23494         $LFS getdirstripe $DIR/$tdir
23495         ls -l $DIR/$tdir/remote_striped_dir
23496         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23497         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23498                 error "create 10 files failed"
23499
23500         for file in $(find $DIR/$tdir); do
23501                 stripe_count=$($LFS getstripe -c $file)
23502                 [ $stripe_count -eq 2 ] ||
23503                         error "wrong stripe $stripe_count for $file"
23504         done
23505
23506         rm -rf $DIR/$tdir
23507 }
23508 run_test 300d "check default stripe under striped directory"
23509
23510 test_300e() {
23511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23512                 skip "Need MDS version at least 2.7.55"
23513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23515
23516         local stripe_count
23517         local file
23518
23519         mkdir -p $DIR/$tdir
23520
23521         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23522                 error "set striped dir error"
23523
23524         touch $DIR/$tdir/striped_dir/a
23525         touch $DIR/$tdir/striped_dir/b
23526         touch $DIR/$tdir/striped_dir/c
23527
23528         mkdir $DIR/$tdir/striped_dir/dir_a
23529         mkdir $DIR/$tdir/striped_dir/dir_b
23530         mkdir $DIR/$tdir/striped_dir/dir_c
23531
23532         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23533                 error "set striped adir under striped dir error"
23534
23535         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23536                 error "set striped bdir under striped dir error"
23537
23538         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23539                 error "set striped cdir under striped dir error"
23540
23541         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23542                 error "rename dir under striped dir fails"
23543
23544         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23545                 error "rename dir under different stripes fails"
23546
23547         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23548                 error "rename file under striped dir should succeed"
23549
23550         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23551                 error "rename dir under striped dir should succeed"
23552
23553         rm -rf $DIR/$tdir
23554 }
23555 run_test 300e "check rename under striped directory"
23556
23557 test_300f() {
23558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23560         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23561                 skip "Need MDS version at least 2.7.55"
23562
23563         local stripe_count
23564         local file
23565
23566         rm -rf $DIR/$tdir
23567         mkdir -p $DIR/$tdir
23568
23569         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23570                 error "set striped dir error"
23571
23572         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23573                 error "set striped dir error"
23574
23575         touch $DIR/$tdir/striped_dir/a
23576         mkdir $DIR/$tdir/striped_dir/dir_a
23577         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23578                 error "create striped dir under striped dir fails"
23579
23580         touch $DIR/$tdir/striped_dir1/b
23581         mkdir $DIR/$tdir/striped_dir1/dir_b
23582         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23583                 error "create striped dir under striped dir fails"
23584
23585         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23586                 error "rename dir under different striped dir should fail"
23587
23588         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23589                 error "rename striped dir under diff striped dir should fail"
23590
23591         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23592                 error "rename file under diff striped dirs fails"
23593
23594         rm -rf $DIR/$tdir
23595 }
23596 run_test 300f "check rename cross striped directory"
23597
23598 test_300_check_default_striped_dir()
23599 {
23600         local dirname=$1
23601         local default_count=$2
23602         local default_index=$3
23603         local stripe_count
23604         local stripe_index
23605         local dir_stripe_index
23606         local dir
23607
23608         echo "checking $dirname $default_count $default_index"
23609         $LFS setdirstripe -D -c $default_count -i $default_index \
23610                                 -H all_char $DIR/$tdir/$dirname ||
23611                 error "set default stripe on striped dir error"
23612         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23613         [ $stripe_count -eq $default_count ] ||
23614                 error "expect $default_count get $stripe_count for $dirname"
23615
23616         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23617         [ $stripe_index -eq $default_index ] ||
23618                 error "expect $default_index get $stripe_index for $dirname"
23619
23620         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23621                                                 error "create dirs failed"
23622
23623         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23624         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23625         for dir in $(find $DIR/$tdir/$dirname/*); do
23626                 stripe_count=$($LFS getdirstripe -c $dir)
23627                 (( $stripe_count == $default_count )) ||
23628                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23629                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23630                 error "stripe count $default_count != $stripe_count for $dir"
23631
23632                 stripe_index=$($LFS getdirstripe -i $dir)
23633                 [ $default_index -eq -1 ] ||
23634                         [ $stripe_index -eq $default_index ] ||
23635                         error "$stripe_index != $default_index for $dir"
23636
23637                 #check default stripe
23638                 stripe_count=$($LFS getdirstripe -D -c $dir)
23639                 [ $stripe_count -eq $default_count ] ||
23640                 error "default count $default_count != $stripe_count for $dir"
23641
23642                 stripe_index=$($LFS getdirstripe -D -i $dir)
23643                 [ $stripe_index -eq $default_index ] ||
23644                 error "default index $default_index != $stripe_index for $dir"
23645         done
23646         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23647 }
23648
23649 test_300g() {
23650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23651         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23652                 skip "Need MDS version at least 2.7.55"
23653
23654         local dir
23655         local stripe_count
23656         local stripe_index
23657
23658         mkdir_on_mdt0 $DIR/$tdir
23659         mkdir $DIR/$tdir/normal_dir
23660
23661         #Checking when client cache stripe index
23662         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23663         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23664                 error "create striped_dir failed"
23665
23666         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23667                 error "create dir0 fails"
23668         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23669         [ $stripe_index -eq 0 ] ||
23670                 error "dir0 expect index 0 got $stripe_index"
23671
23672         mkdir $DIR/$tdir/striped_dir/dir1 ||
23673                 error "create dir1 fails"
23674         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23675         [ $stripe_index -eq 1 ] ||
23676                 error "dir1 expect index 1 got $stripe_index"
23677
23678         #check default stripe count/stripe index
23679         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23680         test_300_check_default_striped_dir normal_dir 1 0
23681         test_300_check_default_striped_dir normal_dir -1 1
23682         test_300_check_default_striped_dir normal_dir 2 -1
23683
23684         #delete default stripe information
23685         echo "delete default stripeEA"
23686         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23687                 error "set default stripe on striped dir error"
23688
23689         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23690         for dir in $(find $DIR/$tdir/normal_dir/*); do
23691                 stripe_count=$($LFS getdirstripe -c $dir)
23692                 [ $stripe_count -eq 0 ] ||
23693                         error "expect 1 get $stripe_count for $dir"
23694         done
23695 }
23696 run_test 300g "check default striped directory for normal directory"
23697
23698 test_300h() {
23699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23700         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23701                 skip "Need MDS version at least 2.7.55"
23702
23703         local dir
23704         local stripe_count
23705
23706         mkdir $DIR/$tdir
23707         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23708                 error "set striped dir error"
23709
23710         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23711         test_300_check_default_striped_dir striped_dir 1 0
23712         test_300_check_default_striped_dir striped_dir -1 1
23713         test_300_check_default_striped_dir striped_dir 2 -1
23714
23715         #delete default stripe information
23716         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23717                 error "set default stripe on striped dir error"
23718
23719         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23720         for dir in $(find $DIR/$tdir/striped_dir/*); do
23721                 stripe_count=$($LFS getdirstripe -c $dir)
23722                 [ $stripe_count -eq 0 ] ||
23723                         error "expect 1 get $stripe_count for $dir"
23724         done
23725 }
23726 run_test 300h "check default striped directory for striped directory"
23727
23728 test_300i() {
23729         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23730         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23731         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23732                 skip "Need MDS version at least 2.7.55"
23733
23734         local stripe_count
23735         local file
23736
23737         mkdir $DIR/$tdir
23738
23739         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23740                 error "set striped dir error"
23741
23742         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23743                 error "create files under striped dir failed"
23744
23745         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23746                 error "set striped hashdir error"
23747
23748         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23749                 error "create dir0 under hash dir failed"
23750         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23751                 error "create dir1 under hash dir failed"
23752         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23753                 error "create dir2 under hash dir failed"
23754
23755         # unfortunately, we need to umount to clear dir layout cache for now
23756         # once we fully implement dir layout, we can drop this
23757         umount_client $MOUNT || error "umount failed"
23758         mount_client $MOUNT || error "mount failed"
23759
23760         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23761         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23762         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23763
23764         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23765                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23766                         error "create crush2 dir $tdir/hashdir/d3 failed"
23767                 $LFS find -H crush2 $DIR/$tdir/hashdir
23768                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23769                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23770
23771                 # mkdir with an invalid hash type (hash=fail_val) from client
23772                 # should be replaced on MDS with a valid (default) hash type
23773                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23774                 $LCTL set_param fail_loc=0x1901 fail_val=99
23775                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23776
23777                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23778                 local expect=$(do_facet mds1 \
23779                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23780                 [[ $hash == $expect ]] ||
23781                         error "d99 hash '$hash' != expected hash '$expect'"
23782         fi
23783
23784         #set the stripe to be unknown hash type on read
23785         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23786         $LCTL set_param fail_loc=0x1901 fail_val=99
23787         for ((i = 0; i < 10; i++)); do
23788                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23789                         error "stat f-$i failed"
23790                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23791         done
23792
23793         touch $DIR/$tdir/striped_dir/f0 &&
23794                 error "create under striped dir with unknown hash should fail"
23795
23796         $LCTL set_param fail_loc=0
23797
23798         umount_client $MOUNT || error "umount failed"
23799         mount_client $MOUNT || error "mount failed"
23800
23801         return 0
23802 }
23803 run_test 300i "client handle unknown hash type striped directory"
23804
23805 test_300j() {
23806         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23808         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23809                 skip "Need MDS version at least 2.7.55"
23810
23811         local stripe_count
23812         local file
23813
23814         mkdir $DIR/$tdir
23815
23816         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23817         $LCTL set_param fail_loc=0x1702
23818         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23819                 error "set striped dir error"
23820
23821         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23822                 error "create files under striped dir failed"
23823
23824         $LCTL set_param fail_loc=0
23825
23826         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23827
23828         return 0
23829 }
23830 run_test 300j "test large update record"
23831
23832 test_300k() {
23833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23835         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23836                 skip "Need MDS version at least 2.7.55"
23837
23838         # this test needs a huge transaction
23839         local kb
23840         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23841              osd*.$FSNAME-MDT0000.kbytestotal")
23842         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23843
23844         local stripe_count
23845         local file
23846
23847         mkdir $DIR/$tdir
23848
23849         #define OBD_FAIL_LARGE_STRIPE   0x1703
23850         $LCTL set_param fail_loc=0x1703
23851         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23852                 error "set striped dir error"
23853         $LCTL set_param fail_loc=0
23854
23855         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23856                 error "getstripeddir fails"
23857         rm -rf $DIR/$tdir/striped_dir ||
23858                 error "unlink striped dir fails"
23859
23860         return 0
23861 }
23862 run_test 300k "test large striped directory"
23863
23864 test_300l() {
23865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23866         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23867         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23868                 skip "Need MDS version at least 2.7.55"
23869
23870         local stripe_index
23871
23872         test_mkdir -p $DIR/$tdir/striped_dir
23873         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23874                         error "chown $RUNAS_ID failed"
23875         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23876                 error "set default striped dir failed"
23877
23878         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23879         $LCTL set_param fail_loc=0x80000158
23880         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23881
23882         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23883         [ $stripe_index -eq 1 ] ||
23884                 error "expect 1 get $stripe_index for $dir"
23885 }
23886 run_test 300l "non-root user to create dir under striped dir with stale layout"
23887
23888 test_300m() {
23889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23890         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23891         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23892                 skip "Need MDS version at least 2.7.55"
23893
23894         mkdir -p $DIR/$tdir/striped_dir
23895         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23896                 error "set default stripes dir error"
23897
23898         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23899
23900         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23901         [ $stripe_count -eq 0 ] ||
23902                         error "expect 0 get $stripe_count for a"
23903
23904         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23905                 error "set default stripes dir error"
23906
23907         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23908
23909         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23910         [ $stripe_count -eq 0 ] ||
23911                         error "expect 0 get $stripe_count for b"
23912
23913         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23914                 error "set default stripes dir error"
23915
23916         mkdir $DIR/$tdir/striped_dir/c &&
23917                 error "default stripe_index is invalid, mkdir c should fails"
23918
23919         rm -rf $DIR/$tdir || error "rmdir fails"
23920 }
23921 run_test 300m "setstriped directory on single MDT FS"
23922
23923 cleanup_300n() {
23924         local list=$(comma_list $(mdts_nodes))
23925
23926         trap 0
23927         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23928 }
23929
23930 test_300n() {
23931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23932         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23933         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23934                 skip "Need MDS version at least 2.7.55"
23935         remote_mds_nodsh && skip "remote MDS with nodsh"
23936
23937         local stripe_index
23938         local list=$(comma_list $(mdts_nodes))
23939
23940         trap cleanup_300n RETURN EXIT
23941         mkdir -p $DIR/$tdir
23942         chmod 777 $DIR/$tdir
23943         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23944                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23945                 error "create striped dir succeeds with gid=0"
23946
23947         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23948         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23949                 error "create striped dir fails with gid=-1"
23950
23951         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23952         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23953                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23954                 error "set default striped dir succeeds with gid=0"
23955
23956
23957         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23958         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23959                 error "set default striped dir fails with gid=-1"
23960
23961
23962         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23963         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23964                                         error "create test_dir fails"
23965         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23966                                         error "create test_dir1 fails"
23967         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23968                                         error "create test_dir2 fails"
23969         cleanup_300n
23970 }
23971 run_test 300n "non-root user to create dir under striped dir with default EA"
23972
23973 test_300o() {
23974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23976         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23977                 skip "Need MDS version at least 2.7.55"
23978
23979         local numfree1
23980         local numfree2
23981
23982         mkdir -p $DIR/$tdir
23983
23984         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23985         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23986         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23987                 skip "not enough free inodes $numfree1 $numfree2"
23988         fi
23989
23990         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23991         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23992         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23993                 skip "not enough free space $numfree1 $numfree2"
23994         fi
23995
23996         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23997                 error "setdirstripe fails"
23998
23999         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24000                 error "create dirs fails"
24001
24002         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24003         ls $DIR/$tdir/striped_dir > /dev/null ||
24004                 error "ls striped dir fails"
24005         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24006                 error "unlink big striped dir fails"
24007 }
24008 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24009
24010 test_300p() {
24011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24012         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24013         remote_mds_nodsh && skip "remote MDS with nodsh"
24014
24015         mkdir_on_mdt0 $DIR/$tdir
24016
24017         #define OBD_FAIL_OUT_ENOSPC     0x1704
24018         do_facet mds2 lctl set_param fail_loc=0x80001704
24019         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24020                  && error "create striped directory should fail"
24021
24022         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24023
24024         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24025         true
24026 }
24027 run_test 300p "create striped directory without space"
24028
24029 test_300q() {
24030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24032
24033         local fd=$(free_fd)
24034         local cmd="exec $fd<$tdir"
24035         cd $DIR
24036         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24037         eval $cmd
24038         cmd="exec $fd<&-"
24039         trap "eval $cmd" EXIT
24040         cd $tdir || error "cd $tdir fails"
24041         rmdir  ../$tdir || error "rmdir $tdir fails"
24042         mkdir local_dir && error "create dir succeeds"
24043         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24044         eval $cmd
24045         return 0
24046 }
24047 run_test 300q "create remote directory under orphan directory"
24048
24049 test_300r() {
24050         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24051                 skip "Need MDS version at least 2.7.55" && return
24052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24053
24054         mkdir $DIR/$tdir
24055
24056         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24057                 error "set striped dir error"
24058
24059         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24060                 error "getstripeddir fails"
24061
24062         local stripe_count
24063         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24064                       awk '/lmv_stripe_count:/ { print $2 }')
24065
24066         [ $MDSCOUNT -ne $stripe_count ] &&
24067                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24068
24069         rm -rf $DIR/$tdir/striped_dir ||
24070                 error "unlink striped dir fails"
24071 }
24072 run_test 300r "test -1 striped directory"
24073
24074 test_300s_helper() {
24075         local count=$1
24076
24077         local stripe_dir=$DIR/$tdir/striped_dir.$count
24078
24079         $LFS mkdir -c $count $stripe_dir ||
24080                 error "lfs mkdir -c error"
24081
24082         $LFS getdirstripe $stripe_dir ||
24083                 error "lfs getdirstripe fails"
24084
24085         local stripe_count
24086         stripe_count=$($LFS getdirstripe $stripe_dir |
24087                       awk '/lmv_stripe_count:/ { print $2 }')
24088
24089         [ $count -ne $stripe_count ] &&
24090                 error_noexit "bad stripe count $stripe_count expected $count"
24091
24092         local dupe_stripes
24093         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24094                 awk '/0x/ {count[$1] += 1}; END {
24095                         for (idx in count) {
24096                                 if (count[idx]>1) {
24097                                         print "index " idx " count " count[idx]
24098                                 }
24099                         }
24100                 }')
24101
24102         if [[ -n "$dupe_stripes" ]] ; then
24103                 lfs getdirstripe $stripe_dir
24104                 error_noexit "Dupe MDT above: $dupe_stripes "
24105         fi
24106
24107         rm -rf $stripe_dir ||
24108                 error_noexit "unlink $stripe_dir fails"
24109 }
24110
24111 test_300s() {
24112         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24113                 skip "Need MDS version at least 2.7.55" && return
24114         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24115
24116         mkdir $DIR/$tdir
24117         for count in $(seq 2 $MDSCOUNT); do
24118                 test_300s_helper $count
24119         done
24120 }
24121 run_test 300s "test lfs mkdir -c without -i"
24122
24123 test_300t() {
24124         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24125                 skip "need MDS 2.14.55 or later"
24126         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24127
24128         local testdir="$DIR/$tdir/striped_dir"
24129         local dir1=$testdir/dir1
24130         local dir2=$testdir/dir2
24131
24132         mkdir -p $testdir
24133
24134         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24135                 error "failed to set default stripe count for $testdir"
24136
24137         mkdir $dir1
24138         local stripe_count=$($LFS getdirstripe -c $dir1)
24139
24140         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24141
24142         local max_count=$((MDSCOUNT - 1))
24143         local mdts=$(comma_list $(mdts_nodes))
24144
24145         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24146         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24147
24148         mkdir $dir2
24149         stripe_count=$($LFS getdirstripe -c $dir2)
24150
24151         (( $stripe_count == $max_count )) || error "wrong stripe count"
24152 }
24153 run_test 300t "test max_mdt_stripecount"
24154
24155 prepare_remote_file() {
24156         mkdir $DIR/$tdir/src_dir ||
24157                 error "create remote source failed"
24158
24159         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24160                  error "cp to remote source failed"
24161         touch $DIR/$tdir/src_dir/a
24162
24163         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24164                 error "create remote target dir failed"
24165
24166         touch $DIR/$tdir/tgt_dir/b
24167
24168         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24169                 error "rename dir cross MDT failed!"
24170
24171         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24172                 error "src_child still exists after rename"
24173
24174         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24175                 error "missing file(a) after rename"
24176
24177         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24178                 error "diff after rename"
24179 }
24180
24181 test_310a() {
24182         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24184
24185         local remote_file=$DIR/$tdir/tgt_dir/b
24186
24187         mkdir -p $DIR/$tdir
24188
24189         prepare_remote_file || error "prepare remote file failed"
24190
24191         #open-unlink file
24192         $OPENUNLINK $remote_file $remote_file ||
24193                 error "openunlink $remote_file failed"
24194         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24195 }
24196 run_test 310a "open unlink remote file"
24197
24198 test_310b() {
24199         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24201
24202         local remote_file=$DIR/$tdir/tgt_dir/b
24203
24204         mkdir -p $DIR/$tdir
24205
24206         prepare_remote_file || error "prepare remote file failed"
24207
24208         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24209         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24210         $CHECKSTAT -t file $remote_file || error "check file failed"
24211 }
24212 run_test 310b "unlink remote file with multiple links while open"
24213
24214 test_310c() {
24215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24216         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24217
24218         local remote_file=$DIR/$tdir/tgt_dir/b
24219
24220         mkdir -p $DIR/$tdir
24221
24222         prepare_remote_file || error "prepare remote file failed"
24223
24224         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24225         multiop_bg_pause $remote_file O_uc ||
24226                         error "mulitop failed for remote file"
24227         MULTIPID=$!
24228         $MULTIOP $DIR/$tfile Ouc
24229         kill -USR1 $MULTIPID
24230         wait $MULTIPID
24231 }
24232 run_test 310c "open-unlink remote file with multiple links"
24233
24234 #LU-4825
24235 test_311() {
24236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24237         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24238         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24239                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24240         remote_mds_nodsh && skip "remote MDS with nodsh"
24241
24242         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24243         local mdts=$(comma_list $(mdts_nodes))
24244
24245         mkdir -p $DIR/$tdir
24246         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24247         createmany -o $DIR/$tdir/$tfile. 1000
24248
24249         # statfs data is not real time, let's just calculate it
24250         old_iused=$((old_iused + 1000))
24251
24252         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24253                         osp.*OST0000*MDT0000.create_count")
24254         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24255                                 osp.*OST0000*MDT0000.max_create_count")
24256         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24257
24258         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24259         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24260         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24261
24262         unlinkmany $DIR/$tdir/$tfile. 1000
24263
24264         do_nodes $mdts "$LCTL set_param -n \
24265                         osp.*OST0000*.max_create_count=$max_count"
24266         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24267                 do_nodes $mdts "$LCTL set_param -n \
24268                                 osp.*OST0000*.create_count=$count"
24269         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24270                         grep "=0" && error "create_count is zero"
24271
24272         local new_iused
24273         for i in $(seq 120); do
24274                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24275                 # system may be too busy to destroy all objs in time, use
24276                 # a somewhat small value to not fail autotest
24277                 [ $((old_iused - new_iused)) -gt 400 ] && break
24278                 sleep 1
24279         done
24280
24281         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24282         [ $((old_iused - new_iused)) -gt 400 ] ||
24283                 error "objs not destroyed after unlink"
24284 }
24285 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24286
24287 zfs_oid_to_objid()
24288 {
24289         local ost=$1
24290         local objid=$2
24291
24292         local vdevdir=$(dirname $(facet_vdevice $ost))
24293         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24294         local zfs_zapid=$(do_facet $ost $cmd |
24295                           grep -w "/O/0/d$((objid%32))" -C 5 |
24296                           awk '/Object/{getline; print $1}')
24297         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24298                           awk "/$objid = /"'{printf $3}')
24299
24300         echo $zfs_objid
24301 }
24302
24303 zfs_object_blksz() {
24304         local ost=$1
24305         local objid=$2
24306
24307         local vdevdir=$(dirname $(facet_vdevice $ost))
24308         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24309         local blksz=$(do_facet $ost $cmd $objid |
24310                       awk '/dblk/{getline; printf $4}')
24311
24312         case "${blksz: -1}" in
24313                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24314                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24315                 *) ;;
24316         esac
24317
24318         echo $blksz
24319 }
24320
24321 test_312() { # LU-4856
24322         remote_ost_nodsh && skip "remote OST with nodsh"
24323         [ "$ost1_FSTYPE" = "zfs" ] ||
24324                 skip_env "the test only applies to zfs"
24325
24326         local max_blksz=$(do_facet ost1 \
24327                           $ZFS get -p recordsize $(facet_device ost1) |
24328                           awk '!/VALUE/{print $3}')
24329
24330         # to make life a little bit easier
24331         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24332         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24333
24334         local tf=$DIR/$tdir/$tfile
24335         touch $tf
24336         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24337
24338         # Get ZFS object id
24339         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24340         # block size change by sequential overwrite
24341         local bs
24342
24343         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24344                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24345
24346                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24347                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24348         done
24349         rm -f $tf
24350
24351         # block size change by sequential append write
24352         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24353         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24354         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24355         local count
24356
24357         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24358                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24359                         oflag=sync conv=notrunc
24360
24361                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24362                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24363                         error "blksz error, actual $blksz, " \
24364                                 "expected: 2 * $count * $PAGE_SIZE"
24365         done
24366         rm -f $tf
24367
24368         # random write
24369         touch $tf
24370         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24371         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24372
24373         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24374         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24375         [ $blksz -eq $PAGE_SIZE ] ||
24376                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24377
24378         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24379         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24380         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24381
24382         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24383         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24384         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24385 }
24386 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24387
24388 test_313() {
24389         remote_ost_nodsh && skip "remote OST with nodsh"
24390
24391         local file=$DIR/$tfile
24392
24393         rm -f $file
24394         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24395
24396         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24397         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24398         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24399                 error "write should failed"
24400         do_facet ost1 "$LCTL set_param fail_loc=0"
24401         rm -f $file
24402 }
24403 run_test 313 "io should fail after last_rcvd update fail"
24404
24405 test_314() {
24406         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24407
24408         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24409         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24410         rm -f $DIR/$tfile
24411         wait_delete_completed
24412         do_facet ost1 "$LCTL set_param fail_loc=0"
24413 }
24414 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24415
24416 test_315() { # LU-618
24417         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24418
24419         local file=$DIR/$tfile
24420         rm -f $file
24421
24422         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24423                 error "multiop file write failed"
24424         $MULTIOP $file oO_RDONLY:r4063232_c &
24425         PID=$!
24426
24427         sleep 2
24428
24429         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24430         kill -USR1 $PID
24431
24432         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24433         rm -f $file
24434 }
24435 run_test 315 "read should be accounted"
24436
24437 test_316() {
24438         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24439         large_xattr_enabled || skip "ea_inode feature disabled"
24440
24441         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24442         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24443         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24444         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24445
24446         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24447 }
24448 run_test 316 "lfs migrate of file with large_xattr enabled"
24449
24450 test_317() {
24451         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24452                 skip "Need MDS version at least 2.11.53"
24453         if [ "$ost1_FSTYPE" == "zfs" ]; then
24454                 skip "LU-10370: no implementation for ZFS"
24455         fi
24456
24457         local trunc_sz
24458         local grant_blk_size
24459
24460         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24461                         awk '/grant_block_size:/ { print $2; exit; }')
24462         #
24463         # Create File of size 5M. Truncate it to below size's and verify
24464         # blocks count.
24465         #
24466         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24467                 error "Create file $DIR/$tfile failed"
24468         stack_trap "rm -f $DIR/$tfile" EXIT
24469
24470         for trunc_sz in 2097152 4097 4000 509 0; do
24471                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24472                         error "truncate $tfile to $trunc_sz failed"
24473                 local sz=$(stat --format=%s $DIR/$tfile)
24474                 local blk=$(stat --format=%b $DIR/$tfile)
24475                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24476                                      grant_blk_size) * 8))
24477
24478                 if [[ $blk -ne $trunc_blk ]]; then
24479                         $(which stat) $DIR/$tfile
24480                         error "Expected Block $trunc_blk got $blk for $tfile"
24481                 fi
24482
24483                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24484                         error "Expected Size $trunc_sz got $sz for $tfile"
24485         done
24486
24487         #
24488         # sparse file test
24489         # Create file with a hole and write actual 65536 bytes which aligned
24490         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24491         #
24492         local bs=65536
24493         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24494                 error "Create file : $DIR/$tfile"
24495
24496         #
24497         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24498         # blocks. The block count must drop to 8.
24499         #
24500         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24501                 ((bs - grant_blk_size) + 1)))
24502         $TRUNCATE $DIR/$tfile $trunc_sz ||
24503                 error "truncate $tfile to $trunc_sz failed"
24504
24505         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24506         sz=$(stat --format=%s $DIR/$tfile)
24507         blk=$(stat --format=%b $DIR/$tfile)
24508
24509         if [[ $blk -ne $trunc_bsz ]]; then
24510                 $(which stat) $DIR/$tfile
24511                 error "Expected Block $trunc_bsz got $blk for $tfile"
24512         fi
24513
24514         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24515                 error "Expected Size $trunc_sz got $sz for $tfile"
24516 }
24517 run_test 317 "Verify blocks get correctly update after truncate"
24518
24519 test_318() {
24520         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24521         local old_max_active=$($LCTL get_param -n \
24522                             ${llite_name}.max_read_ahead_async_active \
24523                             2>/dev/null)
24524
24525         $LCTL set_param llite.*.max_read_ahead_async_active=256
24526         local max_active=$($LCTL get_param -n \
24527                            ${llite_name}.max_read_ahead_async_active \
24528                            2>/dev/null)
24529         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24530
24531         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24532                 error "set max_read_ahead_async_active should succeed"
24533
24534         $LCTL set_param llite.*.max_read_ahead_async_active=512
24535         max_active=$($LCTL get_param -n \
24536                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24537         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24538
24539         # restore @max_active
24540         [ $old_max_active -ne 0 ] && $LCTL set_param \
24541                 llite.*.max_read_ahead_async_active=$old_max_active
24542
24543         local old_threshold=$($LCTL get_param -n \
24544                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24545         local max_per_file_mb=$($LCTL get_param -n \
24546                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24547
24548         local invalid=$(($max_per_file_mb + 1))
24549         $LCTL set_param \
24550                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24551                         && error "set $invalid should fail"
24552
24553         local valid=$(($invalid - 1))
24554         $LCTL set_param \
24555                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24556                         error "set $valid should succeed"
24557         local threshold=$($LCTL get_param -n \
24558                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24559         [ $threshold -eq $valid ] || error \
24560                 "expect threshold $valid got $threshold"
24561         $LCTL set_param \
24562                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24563 }
24564 run_test 318 "Verify async readahead tunables"
24565
24566 test_319() {
24567         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24568
24569         local before=$(date +%s)
24570         local evict
24571         local mdir=$DIR/$tdir
24572         local file=$mdir/xxx
24573
24574         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24575         touch $file
24576
24577 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24578         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24579         $LFS migrate -m1 $mdir &
24580
24581         sleep 1
24582         dd if=$file of=/dev/null
24583         wait
24584         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24585           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24586
24587         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24588 }
24589 run_test 319 "lost lease lock on migrate error"
24590
24591 test_398a() { # LU-4198
24592         local ost1_imp=$(get_osc_import_name client ost1)
24593         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24594                          cut -d'.' -f2)
24595
24596         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24597         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24598
24599         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24600         # request a new lock on client
24601         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24602
24603         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24604         #local lock_count=$($LCTL get_param -n \
24605         #                  ldlm.namespaces.$imp_name.lru_size)
24606         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24607
24608         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24609
24610         # no lock cached, should use lockless DIO and not enqueue new lock
24611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24612                 conv=notrunc ||
24613                 error "dio write failed"
24614         lock_count=$($LCTL get_param -n \
24615                      ldlm.namespaces.$imp_name.lru_size)
24616         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24617
24618         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24619
24620         # no lock cached, should use locked DIO append
24621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24622                 conv=notrunc || error "DIO append failed"
24623         lock_count=$($LCTL get_param -n \
24624                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24625         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24626 }
24627 run_test 398a "direct IO should cancel lock otherwise lockless"
24628
24629 test_398b() { # LU-4198
24630         which fio || skip_env "no fio installed"
24631         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24632
24633         local size=48
24634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24635
24636         local njobs=4
24637         # Single page, multiple pages, stripe size, 4*stripe size
24638         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24639                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24640                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24641                         --numjobs=$njobs --fallocate=none \
24642                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24643                         --filename=$DIR/$tfile &
24644                 bg_pid=$!
24645
24646                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24647                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24648                         --numjobs=$njobs --fallocate=none \
24649                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24650                         --filename=$DIR/$tfile || true
24651                 wait $bg_pid
24652         done
24653
24654         evict=$(do_facet client $LCTL get_param \
24655                 osc.$FSNAME-OST*-osc-*/state |
24656             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24657
24658         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24659                 (do_facet client $LCTL get_param \
24660                         osc.$FSNAME-OST*-osc-*/state;
24661                     error "eviction happened: $evict before:$before")
24662
24663         rm -f $DIR/$tfile
24664 }
24665 run_test 398b "DIO and buffer IO race"
24666
24667 test_398c() { # LU-4198
24668         local ost1_imp=$(get_osc_import_name client ost1)
24669         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24670                          cut -d'.' -f2)
24671
24672         which fio || skip_env "no fio installed"
24673
24674         saved_debug=$($LCTL get_param -n debug)
24675         $LCTL set_param debug=0
24676
24677         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24678         ((size /= 1024)) # by megabytes
24679         ((size /= 2)) # write half of the OST at most
24680         [ $size -gt 40 ] && size=40 #reduce test time anyway
24681
24682         $LFS setstripe -c 1 $DIR/$tfile
24683
24684         # it seems like ldiskfs reserves more space than necessary if the
24685         # writing blocks are not mapped, so it extends the file firstly
24686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24687         cancel_lru_locks osc
24688
24689         # clear and verify rpc_stats later
24690         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24691
24692         local njobs=4
24693         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24694         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24695                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24696                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24697                 --filename=$DIR/$tfile
24698         [ $? -eq 0 ] || error "fio write error"
24699
24700         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24701                 error "Locks were requested while doing AIO"
24702
24703         # get the percentage of 1-page I/O
24704         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24705                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24706                 awk '{print $7}')
24707         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24708
24709         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24710         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24711                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24712                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24713                 --filename=$DIR/$tfile
24714         [ $? -eq 0 ] || error "fio mixed read write error"
24715
24716         echo "AIO with large block size ${size}M"
24717         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24718                 --numjobs=1 --fallocate=none --ioengine=libaio \
24719                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24720                 --filename=$DIR/$tfile
24721         [ $? -eq 0 ] || error "fio large block size failed"
24722
24723         rm -f $DIR/$tfile
24724         $LCTL set_param debug="$saved_debug"
24725 }
24726 run_test 398c "run fio to test AIO"
24727
24728 test_398d() { #  LU-13846
24729         which aiocp || skip_env "no aiocp installed"
24730         local aio_file=$DIR/$tfile.aio
24731
24732         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24733
24734         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24735         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24736         stack_trap "rm -f $DIR/$tfile $aio_file"
24737
24738         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24739
24740         # make sure we don't crash and fail properly
24741         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24742                 error "aio not aligned with PAGE SIZE should fail"
24743
24744         rm -f $DIR/$tfile $aio_file
24745 }
24746 run_test 398d "run aiocp to verify block size > stripe size"
24747
24748 test_398e() {
24749         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24750         touch $DIR/$tfile.new
24751         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24752 }
24753 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24754
24755 test_398f() { #  LU-14687
24756         which aiocp || skip_env "no aiocp installed"
24757         local aio_file=$DIR/$tfile.aio
24758
24759         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24760
24761         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24762         stack_trap "rm -f $DIR/$tfile $aio_file"
24763
24764         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24765         $LCTL set_param fail_loc=0x1418
24766         # make sure we don't crash and fail properly
24767         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24768                 error "aio with page allocation failure succeeded"
24769         $LCTL set_param fail_loc=0
24770         diff $DIR/$tfile $aio_file
24771         [[ $? != 0 ]] || error "no diff after failed aiocp"
24772 }
24773 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24774
24775 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24776 # stripe and i/o size must be > stripe size
24777 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24778 # single RPC in flight.  This test shows async DIO submission is working by
24779 # showing multiple RPCs in flight.
24780 test_398g() { #  LU-13798
24781         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24782
24783         # We need to do some i/o first to acquire enough grant to put our RPCs
24784         # in flight; otherwise a new connection may not have enough grant
24785         # available
24786         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24787                 error "parallel dio failed"
24788         stack_trap "rm -f $DIR/$tfile"
24789
24790         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24791         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24792         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24793         stack_trap "$LCTL set_param -n $pages_per_rpc"
24794
24795         # Recreate file so it's empty
24796         rm -f $DIR/$tfile
24797         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24798         #Pause rpc completion to guarantee we see multiple rpcs in flight
24799         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24800         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24801         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24802
24803         # Clear rpc stats
24804         $LCTL set_param osc.*.rpc_stats=c
24805
24806         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24807                 error "parallel dio failed"
24808         stack_trap "rm -f $DIR/$tfile"
24809
24810         $LCTL get_param osc.*-OST0000-*.rpc_stats
24811         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24812                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24813                 grep "8:" | awk '{print $8}')
24814         # We look at the "8 rpcs in flight" field, and verify A) it is present
24815         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24816         # as expected for an 8M DIO to a file with 1M stripes.
24817         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24818
24819         # Verify turning off parallel dio works as expected
24820         # Clear rpc stats
24821         $LCTL set_param osc.*.rpc_stats=c
24822         $LCTL set_param llite.*.parallel_dio=0
24823         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24824
24825         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24826                 error "dio with parallel dio disabled failed"
24827
24828         # Ideally, we would see only one RPC in flight here, but there is an
24829         # unavoidable race between i/o completion and RPC in flight counting,
24830         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24831         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24832         # So instead we just verify it's always < 8.
24833         $LCTL get_param osc.*-OST0000-*.rpc_stats
24834         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24835                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24836                 grep '^$' -B1 | grep . | awk '{print $1}')
24837         [ $ret != "8:" ] ||
24838                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24839 }
24840 run_test 398g "verify parallel dio async RPC submission"
24841
24842 test_398h() { #  LU-13798
24843         local dio_file=$DIR/$tfile.dio
24844
24845         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24846
24847         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24848         stack_trap "rm -f $DIR/$tfile $dio_file"
24849
24850         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24851                 error "parallel dio failed"
24852         diff $DIR/$tfile $dio_file
24853         [[ $? == 0 ]] || error "file diff after aiocp"
24854 }
24855 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24856
24857 test_398i() { #  LU-13798
24858         local dio_file=$DIR/$tfile.dio
24859
24860         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24861
24862         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24863         stack_trap "rm -f $DIR/$tfile $dio_file"
24864
24865         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24866         $LCTL set_param fail_loc=0x1418
24867         # make sure we don't crash and fail properly
24868         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24869                 error "parallel dio page allocation failure succeeded"
24870         diff $DIR/$tfile $dio_file
24871         [[ $? != 0 ]] || error "no diff after failed aiocp"
24872 }
24873 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24874
24875 test_398j() { #  LU-13798
24876         # Stripe size > RPC size but less than i/o size tests split across
24877         # stripes and RPCs for individual i/o op
24878         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24879
24880         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24881         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24882         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24883         stack_trap "$LCTL set_param -n $pages_per_rpc"
24884
24885         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24886                 error "parallel dio write failed"
24887         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24888
24889         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24890                 error "parallel dio read failed"
24891         diff $DIR/$tfile $DIR/$tfile.2
24892         [[ $? == 0 ]] || error "file diff after parallel dio read"
24893 }
24894 run_test 398j "test parallel dio where stripe size > rpc_size"
24895
24896 test_398k() { #  LU-13798
24897         wait_delete_completed
24898         wait_mds_ost_sync
24899
24900         # 4 stripe file; we will cause out of space on OST0
24901         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24902
24903         # Fill OST0 (if it's not too large)
24904         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24905                    head -n1)
24906         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24907                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24908         fi
24909         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24910         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24911                 error "dd should fill OST0"
24912         stack_trap "rm -f $DIR/$tfile.1"
24913
24914         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24915         err=$?
24916
24917         ls -la $DIR/$tfile
24918         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24919                 error "file is not 0 bytes in size"
24920
24921         # dd above should not succeed, but don't error until here so we can
24922         # get debug info above
24923         [[ $err != 0 ]] ||
24924                 error "parallel dio write with enospc succeeded"
24925         stack_trap "rm -f $DIR/$tfile"
24926 }
24927 run_test 398k "test enospc on first stripe"
24928
24929 test_398l() { #  LU-13798
24930         wait_delete_completed
24931         wait_mds_ost_sync
24932
24933         # 4 stripe file; we will cause out of space on OST0
24934         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24935         # happens on the second i/o chunk we issue
24936         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24937
24938         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24939         stack_trap "rm -f $DIR/$tfile"
24940
24941         # Fill OST0 (if it's not too large)
24942         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24943                    head -n1)
24944         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24945                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24946         fi
24947         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24948         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24949                 error "dd should fill OST0"
24950         stack_trap "rm -f $DIR/$tfile.1"
24951
24952         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24953         err=$?
24954         stack_trap "rm -f $DIR/$tfile.2"
24955
24956         # Check that short write completed as expected
24957         ls -la $DIR/$tfile.2
24958         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24959                 error "file is not 1M in size"
24960
24961         # dd above should not succeed, but don't error until here so we can
24962         # get debug info above
24963         [[ $err != 0 ]] ||
24964                 error "parallel dio write with enospc succeeded"
24965
24966         # Truncate source file to same length as output file and diff them
24967         $TRUNCATE $DIR/$tfile 1048576
24968         diff $DIR/$tfile $DIR/$tfile.2
24969         [[ $? == 0 ]] || error "data incorrect after short write"
24970 }
24971 run_test 398l "test enospc on intermediate stripe/RPC"
24972
24973 test_398m() { #  LU-13798
24974         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24975
24976         # Set up failure on OST0, the first stripe:
24977         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24978         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24979         # So this fail_val specifies OST0
24980         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24981         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24982
24983         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24984                 error "parallel dio write with failure on first stripe succeeded"
24985         stack_trap "rm -f $DIR/$tfile"
24986         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24987
24988         # Place data in file for read
24989         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24990                 error "parallel dio write failed"
24991
24992         # Fail read on OST0, first stripe
24993         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24994         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24995         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24996                 error "parallel dio read with error on first stripe succeeded"
24997         rm -f $DIR/$tfile.2
24998         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24999
25000         # Switch to testing on OST1, second stripe
25001         # Clear file contents, maintain striping
25002         echo > $DIR/$tfile
25003         # Set up failure on OST1, second stripe:
25004         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25005         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25006
25007         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25008                 error "parallel dio write with failure on first stripe succeeded"
25009         stack_trap "rm -f $DIR/$tfile"
25010         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25011
25012         # Place data in file for read
25013         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25014                 error "parallel dio write failed"
25015
25016         # Fail read on OST1, second stripe
25017         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25018         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25019         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25020                 error "parallel dio read with error on first stripe succeeded"
25021         rm -f $DIR/$tfile.2
25022         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25023 }
25024 run_test 398m "test RPC failures with parallel dio"
25025
25026 # Parallel submission of DIO should not cause problems for append, but it's
25027 # important to verify.
25028 test_398n() { #  LU-13798
25029         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25030
25031         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25032                 error "dd to create source file failed"
25033         stack_trap "rm -f $DIR/$tfile"
25034
25035         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25036                 error "parallel dio write with failure on second stripe succeeded"
25037         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25038         diff $DIR/$tfile $DIR/$tfile.1
25039         [[ $? == 0 ]] || error "data incorrect after append"
25040
25041 }
25042 run_test 398n "test append with parallel DIO"
25043
25044 test_fake_rw() {
25045         local read_write=$1
25046         if [ "$read_write" = "write" ]; then
25047                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25048         elif [ "$read_write" = "read" ]; then
25049                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25050         else
25051                 error "argument error"
25052         fi
25053
25054         # turn off debug for performance testing
25055         local saved_debug=$($LCTL get_param -n debug)
25056         $LCTL set_param debug=0
25057
25058         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25059
25060         # get ost1 size - $FSNAME-OST0000
25061         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25062         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25063         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25064
25065         if [ "$read_write" = "read" ]; then
25066                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25067         fi
25068
25069         local start_time=$(date +%s.%N)
25070         $dd_cmd bs=1M count=$blocks oflag=sync ||
25071                 error "real dd $read_write error"
25072         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25073
25074         if [ "$read_write" = "write" ]; then
25075                 rm -f $DIR/$tfile
25076         fi
25077
25078         # define OBD_FAIL_OST_FAKE_RW           0x238
25079         do_facet ost1 $LCTL set_param fail_loc=0x238
25080
25081         local start_time=$(date +%s.%N)
25082         $dd_cmd bs=1M count=$blocks oflag=sync ||
25083                 error "fake dd $read_write error"
25084         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25085
25086         if [ "$read_write" = "write" ]; then
25087                 # verify file size
25088                 cancel_lru_locks osc
25089                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25090                         error "$tfile size not $blocks MB"
25091         fi
25092         do_facet ost1 $LCTL set_param fail_loc=0
25093
25094         echo "fake $read_write $duration_fake vs. normal $read_write" \
25095                 "$duration in seconds"
25096         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25097                 error_not_in_vm "fake write is slower"
25098
25099         $LCTL set_param -n debug="$saved_debug"
25100         rm -f $DIR/$tfile
25101 }
25102 test_399a() { # LU-7655 for OST fake write
25103         remote_ost_nodsh && skip "remote OST with nodsh"
25104
25105         test_fake_rw write
25106 }
25107 run_test 399a "fake write should not be slower than normal write"
25108
25109 test_399b() { # LU-8726 for OST fake read
25110         remote_ost_nodsh && skip "remote OST with nodsh"
25111         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25112                 skip_env "ldiskfs only test"
25113         fi
25114
25115         test_fake_rw read
25116 }
25117 run_test 399b "fake read should not be slower than normal read"
25118
25119 test_400a() { # LU-1606, was conf-sanity test_74
25120         if ! which $CC > /dev/null 2>&1; then
25121                 skip_env "$CC is not installed"
25122         fi
25123
25124         local extra_flags=''
25125         local out=$TMP/$tfile
25126         local prefix=/usr/include/lustre
25127         local prog
25128
25129         # Oleg removes c files in his test rig so test if any c files exist
25130         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25131                 skip_env "Needed c test files are missing"
25132
25133         if ! [[ -d $prefix ]]; then
25134                 # Assume we're running in tree and fixup the include path.
25135                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25136                 extra_flags+=" -L$LUSTRE/utils/.lib"
25137         fi
25138
25139         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25140                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25141                         error "client api broken"
25142         done
25143         rm -f $out
25144 }
25145 run_test 400a "Lustre client api program can compile and link"
25146
25147 test_400b() { # LU-1606, LU-5011
25148         local header
25149         local out=$TMP/$tfile
25150         local prefix=/usr/include/linux/lustre
25151
25152         # We use a hard coded prefix so that this test will not fail
25153         # when run in tree. There are headers in lustre/include/lustre/
25154         # that are not packaged (like lustre_idl.h) and have more
25155         # complicated include dependencies (like config.h and lnet/types.h).
25156         # Since this test about correct packaging we just skip them when
25157         # they don't exist (see below) rather than try to fixup cppflags.
25158
25159         if ! which $CC > /dev/null 2>&1; then
25160                 skip_env "$CC is not installed"
25161         fi
25162
25163         for header in $prefix/*.h; do
25164                 if ! [[ -f "$header" ]]; then
25165                         continue
25166                 fi
25167
25168                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25169                         continue # lustre_ioctl.h is internal header
25170                 fi
25171
25172                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25173                         error "cannot compile '$header'"
25174         done
25175         rm -f $out
25176 }
25177 run_test 400b "packaged headers can be compiled"
25178
25179 test_401a() { #LU-7437
25180         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25181         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25182
25183         #count the number of parameters by "list_param -R"
25184         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25185         #count the number of parameters by listing proc files
25186         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25187         echo "proc_dirs='$proc_dirs'"
25188         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25189         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25190                       sort -u | wc -l)
25191
25192         [ $params -eq $procs ] ||
25193                 error "found $params parameters vs. $procs proc files"
25194
25195         # test the list_param -D option only returns directories
25196         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25197         #count the number of parameters by listing proc directories
25198         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25199                 sort -u | wc -l)
25200
25201         [ $params -eq $procs ] ||
25202                 error "found $params parameters vs. $procs proc files"
25203 }
25204 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25205
25206 test_401b() {
25207         # jobid_var may not allow arbitrary values, so use jobid_name
25208         # if available
25209         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25210                 local testname=jobid_name tmp='testing%p'
25211         else
25212                 local testname=jobid_var tmp=testing
25213         fi
25214
25215         local save=$($LCTL get_param -n $testname)
25216
25217         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25218                 error "no error returned when setting bad parameters"
25219
25220         local jobid_new=$($LCTL get_param -n foe $testname baz)
25221         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25222
25223         $LCTL set_param -n fog=bam $testname=$save bat=fog
25224         local jobid_old=$($LCTL get_param -n foe $testname bag)
25225         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25226 }
25227 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25228
25229 test_401c() {
25230         # jobid_var may not allow arbitrary values, so use jobid_name
25231         # if available
25232         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25233                 local testname=jobid_name
25234         else
25235                 local testname=jobid_var
25236         fi
25237
25238         local jobid_var_old=$($LCTL get_param -n $testname)
25239         local jobid_var_new
25240
25241         $LCTL set_param $testname= &&
25242                 error "no error returned for 'set_param a='"
25243
25244         jobid_var_new=$($LCTL get_param -n $testname)
25245         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25246                 error "$testname was changed by setting without value"
25247
25248         $LCTL set_param $testname &&
25249                 error "no error returned for 'set_param a'"
25250
25251         jobid_var_new=$($LCTL get_param -n $testname)
25252         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25253                 error "$testname was changed by setting without value"
25254 }
25255 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25256
25257 test_401d() {
25258         # jobid_var may not allow arbitrary values, so use jobid_name
25259         # if available
25260         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25261                 local testname=jobid_name new_value='foo=bar%p'
25262         else
25263                 local testname=jobid_var new_valuie=foo=bar
25264         fi
25265
25266         local jobid_var_old=$($LCTL get_param -n $testname)
25267         local jobid_var_new
25268
25269         $LCTL set_param $testname=$new_value ||
25270                 error "'set_param a=b' did not accept a value containing '='"
25271
25272         jobid_var_new=$($LCTL get_param -n $testname)
25273         [[ "$jobid_var_new" == "$new_value" ]] ||
25274                 error "'set_param a=b' failed on a value containing '='"
25275
25276         # Reset the $testname to test the other format
25277         $LCTL set_param $testname=$jobid_var_old
25278         jobid_var_new=$($LCTL get_param -n $testname)
25279         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25280                 error "failed to reset $testname"
25281
25282         $LCTL set_param $testname $new_value ||
25283                 error "'set_param a b' did not accept a value containing '='"
25284
25285         jobid_var_new=$($LCTL get_param -n $testname)
25286         [[ "$jobid_var_new" == "$new_value" ]] ||
25287                 error "'set_param a b' failed on a value containing '='"
25288
25289         $LCTL set_param $testname $jobid_var_old
25290         jobid_var_new=$($LCTL get_param -n $testname)
25291         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25292                 error "failed to reset $testname"
25293 }
25294 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25295
25296 test_401e() { # LU-14779
25297         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25298                 error "lctl list_param MGC* failed"
25299         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25300         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25301                 error "lctl get_param lru_size failed"
25302 }
25303 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25304
25305 test_402() {
25306         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25307         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25308                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25309         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25310                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25311                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25312         remote_mds_nodsh && skip "remote MDS with nodsh"
25313
25314         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25315 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25316         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25317         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25318                 echo "Touch failed - OK"
25319 }
25320 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25321
25322 test_403() {
25323         local file1=$DIR/$tfile.1
25324         local file2=$DIR/$tfile.2
25325         local tfile=$TMP/$tfile
25326
25327         rm -f $file1 $file2 $tfile
25328
25329         touch $file1
25330         ln $file1 $file2
25331
25332         # 30 sec OBD_TIMEOUT in ll_getattr()
25333         # right before populating st_nlink
25334         $LCTL set_param fail_loc=0x80001409
25335         stat -c %h $file1 > $tfile &
25336
25337         # create an alias, drop all locks and reclaim the dentry
25338         < $file2
25339         cancel_lru_locks mdc
25340         cancel_lru_locks osc
25341         sysctl -w vm.drop_caches=2
25342
25343         wait
25344
25345         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25346
25347         rm -f $tfile $file1 $file2
25348 }
25349 run_test 403 "i_nlink should not drop to zero due to aliasing"
25350
25351 test_404() { # LU-6601
25352         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25353                 skip "Need server version newer than 2.8.52"
25354         remote_mds_nodsh && skip "remote MDS with nodsh"
25355
25356         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25357                 awk '/osp .*-osc-MDT/ { print $4}')
25358
25359         local osp
25360         for osp in $mosps; do
25361                 echo "Deactivate: " $osp
25362                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25363                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25364                         awk -vp=$osp '$4 == p { print $2 }')
25365                 [ $stat = IN ] || {
25366                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25367                         error "deactivate error"
25368                 }
25369                 echo "Activate: " $osp
25370                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25371                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25372                         awk -vp=$osp '$4 == p { print $2 }')
25373                 [ $stat = UP ] || {
25374                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25375                         error "activate error"
25376                 }
25377         done
25378 }
25379 run_test 404 "validate manual {de}activated works properly for OSPs"
25380
25381 test_405() {
25382         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25383         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25384                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25385                         skip "Layout swap lock is not supported"
25386
25387         check_swap_layouts_support
25388         check_swap_layout_no_dom $DIR
25389
25390         test_mkdir $DIR/$tdir
25391         swap_lock_test -d $DIR/$tdir ||
25392                 error "One layout swap locked test failed"
25393 }
25394 run_test 405 "Various layout swap lock tests"
25395
25396 test_406() {
25397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25398         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25399         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25401         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25402                 skip "Need MDS version at least 2.8.50"
25403
25404         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25405         local test_pool=$TESTNAME
25406
25407         pool_add $test_pool || error "pool_add failed"
25408         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25409                 error "pool_add_targets failed"
25410
25411         save_layout_restore_at_exit $MOUNT
25412
25413         # parent set default stripe count only, child will stripe from both
25414         # parent and fs default
25415         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25416                 error "setstripe $MOUNT failed"
25417         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25418         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25419         for i in $(seq 10); do
25420                 local f=$DIR/$tdir/$tfile.$i
25421                 touch $f || error "touch failed"
25422                 local count=$($LFS getstripe -c $f)
25423                 [ $count -eq $OSTCOUNT ] ||
25424                         error "$f stripe count $count != $OSTCOUNT"
25425                 local offset=$($LFS getstripe -i $f)
25426                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25427                 local size=$($LFS getstripe -S $f)
25428                 [ $size -eq $((def_stripe_size * 2)) ] ||
25429                         error "$f stripe size $size != $((def_stripe_size * 2))"
25430                 local pool=$($LFS getstripe -p $f)
25431                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25432         done
25433
25434         # change fs default striping, delete parent default striping, now child
25435         # will stripe from new fs default striping only
25436         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25437                 error "change $MOUNT default stripe failed"
25438         $LFS setstripe -c 0 $DIR/$tdir ||
25439                 error "delete $tdir default stripe failed"
25440         for i in $(seq 11 20); do
25441                 local f=$DIR/$tdir/$tfile.$i
25442                 touch $f || error "touch $f failed"
25443                 local count=$($LFS getstripe -c $f)
25444                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25445                 local offset=$($LFS getstripe -i $f)
25446                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25447                 local size=$($LFS getstripe -S $f)
25448                 [ $size -eq $def_stripe_size ] ||
25449                         error "$f stripe size $size != $def_stripe_size"
25450                 local pool=$($LFS getstripe -p $f)
25451                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25452         done
25453
25454         unlinkmany $DIR/$tdir/$tfile. 1 20
25455
25456         local f=$DIR/$tdir/$tfile
25457         pool_remove_all_targets $test_pool $f
25458         pool_remove $test_pool $f
25459 }
25460 run_test 406 "DNE support fs default striping"
25461
25462 test_407() {
25463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25464         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25465                 skip "Need MDS version at least 2.8.55"
25466         remote_mds_nodsh && skip "remote MDS with nodsh"
25467
25468         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25469                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25470         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25471                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25472         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25473
25474         #define OBD_FAIL_DT_TXN_STOP    0x2019
25475         for idx in $(seq $MDSCOUNT); do
25476                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25477         done
25478         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25479         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25480                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25481         true
25482 }
25483 run_test 407 "transaction fail should cause operation fail"
25484
25485 test_408() {
25486         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25487
25488         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25489         lctl set_param fail_loc=0x8000040a
25490         # let ll_prepare_partial_page() fail
25491         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25492
25493         rm -f $DIR/$tfile
25494
25495         # create at least 100 unused inodes so that
25496         # shrink_icache_memory(0) should not return 0
25497         touch $DIR/$tfile-{0..100}
25498         rm -f $DIR/$tfile-{0..100}
25499         sync
25500
25501         echo 2 > /proc/sys/vm/drop_caches
25502 }
25503 run_test 408 "drop_caches should not hang due to page leaks"
25504
25505 test_409()
25506 {
25507         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25508
25509         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25510         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25511         touch $DIR/$tdir/guard || error "(2) Fail to create"
25512
25513         local PREFIX=$(str_repeat 'A' 128)
25514         echo "Create 1K hard links start at $(date)"
25515         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25516                 error "(3) Fail to hard link"
25517
25518         echo "Links count should be right although linkEA overflow"
25519         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25520         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25521         [ $linkcount -eq 1001 ] ||
25522                 error "(5) Unexpected hard links count: $linkcount"
25523
25524         echo "List all links start at $(date)"
25525         ls -l $DIR/$tdir/foo > /dev/null ||
25526                 error "(6) Fail to list $DIR/$tdir/foo"
25527
25528         echo "Unlink hard links start at $(date)"
25529         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25530                 error "(7) Fail to unlink"
25531         echo "Unlink hard links finished at $(date)"
25532 }
25533 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25534
25535 test_410()
25536 {
25537         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25538                 skip "Need client version at least 2.9.59"
25539         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25540                 skip "Need MODULES build"
25541
25542         # Create a file, and stat it from the kernel
25543         local testfile=$DIR/$tfile
25544         touch $testfile
25545
25546         local run_id=$RANDOM
25547         local my_ino=$(stat --format "%i" $testfile)
25548
25549         # Try to insert the module. This will always fail as the
25550         # module is designed to not be inserted.
25551         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25552             &> /dev/null
25553
25554         # Anything but success is a test failure
25555         dmesg | grep -q \
25556             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25557             error "no inode match"
25558 }
25559 run_test 410 "Test inode number returned from kernel thread"
25560
25561 cleanup_test411_cgroup() {
25562         trap 0
25563         rmdir "$1"
25564 }
25565
25566 test_411() {
25567         local cg_basedir=/sys/fs/cgroup/memory
25568         # LU-9966
25569         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25570                 skip "no setup for cgroup"
25571
25572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25573                 error "test file creation failed"
25574         cancel_lru_locks osc
25575
25576         # Create a very small memory cgroup to force a slab allocation error
25577         local cgdir=$cg_basedir/osc_slab_alloc
25578         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25579         trap "cleanup_test411_cgroup $cgdir" EXIT
25580         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25581         echo 1M > $cgdir/memory.limit_in_bytes
25582
25583         # Should not LBUG, just be killed by oom-killer
25584         # dd will return 0 even allocation failure in some environment.
25585         # So don't check return value
25586         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25587         cleanup_test411_cgroup $cgdir
25588
25589         return 0
25590 }
25591 run_test 411 "Slab allocation error with cgroup does not LBUG"
25592
25593 test_412() {
25594         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25595         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25596                 skip "Need server version at least 2.10.55"
25597
25598         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25599                 error "mkdir failed"
25600         $LFS getdirstripe $DIR/$tdir
25601         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25602         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25603                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25604         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25605         [ $stripe_count -eq 2 ] ||
25606                 error "expect 2 get $stripe_count"
25607
25608         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25609
25610         local index
25611         local index2
25612
25613         # subdirs should be on the same MDT as parent
25614         for i in $(seq 0 $((MDSCOUNT - 1))); do
25615                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25616                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25617                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25618                 (( index == i )) || error "mdt$i/sub on MDT$index"
25619         done
25620
25621         # stripe offset -1, ditto
25622         for i in {1..10}; do
25623                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25624                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25625                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25626                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25627                 (( index == index2 )) ||
25628                         error "qos$i on MDT$index, sub on MDT$index2"
25629         done
25630
25631         local testdir=$DIR/$tdir/inherit
25632
25633         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25634         # inherit 2 levels
25635         for i in 1 2; do
25636                 testdir=$testdir/s$i
25637                 mkdir $testdir || error "mkdir $testdir failed"
25638                 index=$($LFS getstripe -m $testdir)
25639                 (( index == 1 )) ||
25640                         error "$testdir on MDT$index"
25641         done
25642
25643         # not inherit any more
25644         testdir=$testdir/s3
25645         mkdir $testdir || error "mkdir $testdir failed"
25646         getfattr -d -m dmv $testdir | grep dmv &&
25647                 error "default LMV set on $testdir" || true
25648 }
25649 run_test 412 "mkdir on specific MDTs"
25650
25651 TEST413_COUNT=${TEST413_COUNT:-200}
25652 generate_uneven_mdts() {
25653         local threshold=$1
25654         local lmv_qos_maxage
25655         local lod_qos_maxage
25656         local ffree
25657         local bavail
25658         local max
25659         local min
25660         local max_index
25661         local min_index
25662         local tmp
25663         local i
25664
25665         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25666         $LCTL set_param lmv.*.qos_maxage=1
25667         stack_trap "$LCTL set_param \
25668                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25669         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25670                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25671         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25672                 lod.*.mdt_qos_maxage=1
25673         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25674                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25675
25676         echo
25677         echo "Check for uneven MDTs: "
25678
25679         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25680         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25681         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25682
25683         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25684         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25685         max_index=0
25686         min_index=0
25687         for ((i = 1; i < ${#ffree[@]}; i++)); do
25688                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25689                 if [ $tmp -gt $max ]; then
25690                         max=$tmp
25691                         max_index=$i
25692                 fi
25693                 if [ $tmp -lt $min ]; then
25694                         min=$tmp
25695                         min_index=$i
25696                 fi
25697         done
25698
25699         (( ${ffree[min_index]} > 0 )) ||
25700                 skip "no free files in MDT$min_index"
25701         (( ${ffree[min_index]} < 10000000 )) ||
25702                 skip "too many free files in MDT$min_index"
25703
25704         # Check if we need to generate uneven MDTs
25705         local diff=$(((max - min) * 100 / min))
25706         local testdir=$DIR/$tdir-fillmdt
25707         local start
25708
25709         i=0
25710         while (( diff < threshold )); do
25711                 mkdir -p $testdir
25712                 # generate uneven MDTs, create till $threshold% diff
25713                 echo -n "weight diff=$diff% must be > $threshold% ..."
25714                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25715                 testdir=$DIR/$tdir-fillmdt/$i
25716                 [ -d $testdir ] && continue
25717                 $LFS mkdir -i $min_index $testdir ||
25718                         error "mkdir $testdir failed"
25719                 $LFS setstripe -E 1M -L mdt $testdir ||
25720                         error "setstripe $testdir failed"
25721                 start=$SECONDS
25722                 for ((F=0; F < TEST413_COUNT; F++)); do
25723                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25724                                 /dev/null 2>&1 || error "dd $F failed"
25725                 done
25726                 sync; sleep 1; sync
25727
25728                 # wait for QOS to update
25729                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25730
25731                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25732                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25733                 max=$(((${ffree[max_index]} >> 8) *
25734                         (${bavail[max_index]} * bsize >> 16)))
25735                 min=$(((${ffree[min_index]} >> 8) *
25736                         (${bavail[min_index]} * bsize >> 16)))
25737                 diff=$(((max - min) * 100 / min))
25738                 i=$((i + 1))
25739         done
25740
25741         echo "MDT filesfree available: ${ffree[*]}"
25742         echo "MDT blocks available: ${bavail[*]}"
25743         echo "weight diff=$diff%"
25744 }
25745
25746 test_qos_mkdir() {
25747         local mkdir_cmd=$1
25748         local stripe_count=$2
25749         local mdts=$(comma_list $(mdts_nodes))
25750
25751         local testdir
25752         local lmv_qos_prio_free
25753         local lmv_qos_threshold_rr
25754         local lmv_qos_maxage
25755         local lod_qos_prio_free
25756         local lod_qos_threshold_rr
25757         local lod_qos_maxage
25758         local count
25759         local i
25760
25761         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25762         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25763         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25764                 head -n1)
25765         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25766         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25767         stack_trap "$LCTL set_param \
25768                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25769         stack_trap "$LCTL set_param \
25770                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25771         stack_trap "$LCTL set_param \
25772                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25773
25774         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25775                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25776         lod_qos_prio_free=${lod_qos_prio_free%%%}
25777         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25778                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25779         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25780         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25781                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25782         stack_trap "do_nodes $mdts $LCTL set_param \
25783                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25784         stack_trap "do_nodes $mdts $LCTL set_param \
25785                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25786         stack_trap "do_nodes $mdts $LCTL set_param \
25787                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25788
25789         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25790         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25791
25792         testdir=$DIR/$tdir-s$stripe_count/rr
25793
25794         local stripe_index=$($LFS getstripe -m $testdir)
25795         local test_mkdir_rr=true
25796
25797         getfattr -d -m dmv -e hex $testdir | grep dmv
25798         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25799                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25800                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25801                         test_mkdir_rr=false
25802         fi
25803
25804         echo
25805         $test_mkdir_rr &&
25806                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25807                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25808
25809         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25810         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25811                 eval $mkdir_cmd $testdir/subdir$i ||
25812                         error "$mkdir_cmd subdir$i failed"
25813         done
25814
25815         for (( i = 0; i < $MDSCOUNT; i++ )); do
25816                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25817                 echo "$count directories created on MDT$i"
25818                 if $test_mkdir_rr; then
25819                         (( $count == 100 )) ||
25820                                 error "subdirs are not evenly distributed"
25821                 elif (( $i == $stripe_index )); then
25822                         (( $count == 100 * MDSCOUNT )) ||
25823                                 error "$count subdirs created on MDT$i"
25824                 else
25825                         (( $count == 0 )) ||
25826                                 error "$count subdirs created on MDT$i"
25827                 fi
25828
25829                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25830                         count=$($LFS getdirstripe $testdir/* |
25831                                 grep -c -P "^\s+$i\t")
25832                         echo "$count stripes created on MDT$i"
25833                         # deviation should < 5% of average
25834                         (( $count >= 95 * stripe_count &&
25835                            $count <= 105 * stripe_count)) ||
25836                                 error "stripes are not evenly distributed"
25837                 fi
25838         done
25839
25840         echo
25841         echo "Check for uneven MDTs: "
25842
25843         local ffree
25844         local bavail
25845         local max
25846         local min
25847         local max_index
25848         local min_index
25849         local tmp
25850
25851         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25852         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25853         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25854
25855         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25856         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25857         max_index=0
25858         min_index=0
25859         for ((i = 1; i < ${#ffree[@]}; i++)); do
25860                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25861                 if [ $tmp -gt $max ]; then
25862                         max=$tmp
25863                         max_index=$i
25864                 fi
25865                 if [ $tmp -lt $min ]; then
25866                         min=$tmp
25867                         min_index=$i
25868                 fi
25869         done
25870
25871         (( ${ffree[min_index]} > 0 )) ||
25872                 skip "no free files in MDT$min_index"
25873         (( ${ffree[min_index]} < 10000000 )) ||
25874                 skip "too many free files in MDT$min_index"
25875
25876         echo "MDT filesfree available: ${ffree[*]}"
25877         echo "MDT blocks available: ${bavail[*]}"
25878         echo "weight diff=$(((max - min) * 100 / min))%"
25879         echo
25880         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25881
25882         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25883         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25884         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25885         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25886         # decrease statfs age, so that it can be updated in time
25887         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25888         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25889
25890         sleep 1
25891
25892         testdir=$DIR/$tdir-s$stripe_count/qos
25893         local num=200
25894
25895         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25896         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25897                 eval $mkdir_cmd $testdir/subdir$i ||
25898                         error "$mkdir_cmd subdir$i failed"
25899         done
25900
25901         max=0
25902         for (( i = 0; i < $MDSCOUNT; i++ )); do
25903                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25904                 (( count > max )) && max=$count
25905                 echo "$count directories created on MDT$i"
25906         done
25907
25908         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25909
25910         # D-value should > 10% of averge
25911         (( max - min > num / 10 )) ||
25912                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25913
25914         # ditto for stripes
25915         if (( stripe_count > 1 )); then
25916                 max=0
25917                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25918                         count=$($LFS getdirstripe $testdir/* |
25919                                 grep -c -P "^\s+$i\t")
25920                         (( count > max )) && max=$count
25921                         echo "$count stripes created on MDT$i"
25922                 done
25923
25924                 min=$($LFS getdirstripe $testdir/* |
25925                         grep -c -P "^\s+$min_index\t")
25926                 (( max - min > num * stripe_count / 10 )) ||
25927                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25928         fi
25929 }
25930
25931 most_full_mdt() {
25932         local ffree
25933         local bavail
25934         local bsize
25935         local min
25936         local min_index
25937         local tmp
25938
25939         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25940         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25941         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25942
25943         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25944         min_index=0
25945         for ((i = 1; i < ${#ffree[@]}; i++)); do
25946                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25947                 (( tmp < min )) && min=$tmp && min_index=$i
25948         done
25949
25950         echo -n $min_index
25951 }
25952
25953 test_413a() {
25954         [ $MDSCOUNT -lt 2 ] &&
25955                 skip "We need at least 2 MDTs for this test"
25956
25957         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25958                 skip "Need server version at least 2.12.52"
25959
25960         local stripe_count
25961
25962         generate_uneven_mdts 100
25963         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25964                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25965                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25966                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25967                         error "mkdir failed"
25968                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25969         done
25970 }
25971 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25972
25973 test_413b() {
25974         [ $MDSCOUNT -lt 2 ] &&
25975                 skip "We need at least 2 MDTs for this test"
25976
25977         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25978                 skip "Need server version at least 2.12.52"
25979
25980         local testdir
25981         local stripe_count
25982
25983         generate_uneven_mdts 100
25984         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25985                 testdir=$DIR/$tdir-s$stripe_count
25986                 mkdir $testdir || error "mkdir $testdir failed"
25987                 mkdir $testdir/rr || error "mkdir rr failed"
25988                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25989                         error "mkdir qos failed"
25990                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25991                         $testdir/rr || error "setdirstripe rr failed"
25992                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25993                         error "setdirstripe failed"
25994                 test_qos_mkdir "mkdir" $stripe_count
25995         done
25996 }
25997 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25998
25999 test_413c() {
26000         (( $MDSCOUNT >= 2 )) ||
26001                 skip "We need at least 2 MDTs for this test"
26002
26003         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26004                 skip "Need server version at least 2.14.51"
26005
26006         local testdir
26007         local inherit
26008         local inherit_rr
26009
26010         testdir=$DIR/${tdir}-s1
26011         mkdir $testdir || error "mkdir $testdir failed"
26012         mkdir $testdir/rr || error "mkdir rr failed"
26013         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26014         # default max_inherit is -1, default max_inherit_rr is 0
26015         $LFS setdirstripe -D -c 1 $testdir/rr ||
26016                 error "setdirstripe rr failed"
26017         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26018                 error "setdirstripe qos failed"
26019         test_qos_mkdir "mkdir" 1
26020
26021         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26022         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26023         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26024         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26025         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26026
26027         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26028         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26029         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26030         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26031         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26032         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26033         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26034                 error "level2 shouldn't have default LMV" || true
26035 }
26036 run_test 413c "mkdir with default LMV max inherit rr"
26037
26038 test_413d() {
26039         (( MDSCOUNT >= 2 )) ||
26040                 skip "We need at least 2 MDTs for this test"
26041
26042         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26043                 skip "Need server version at least 2.14.51"
26044
26045         local lmv_qos_threshold_rr
26046
26047         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26048                 head -n1)
26049         stack_trap "$LCTL set_param \
26050                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26051
26052         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26053         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26054         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26055                 error "$tdir shouldn't have default LMV"
26056         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26057                 error "mkdir sub failed"
26058
26059         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26060
26061         (( count == 100 )) || error "$count subdirs on MDT0"
26062 }
26063 run_test 413d "inherit ROOT default LMV"
26064
26065 test_413e() {
26066         (( MDSCOUNT >= 2 )) ||
26067                 skip "We need at least 2 MDTs for this test"
26068         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26069                 skip "Need server version at least 2.14.55"
26070
26071         local testdir=$DIR/$tdir
26072         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26073         local max_inherit
26074         local sub_max_inherit
26075
26076         mkdir -p $testdir || error "failed to create $testdir"
26077
26078         # set default max-inherit to -1 if stripe count is 0 or 1
26079         $LFS setdirstripe -D -c 1 $testdir ||
26080                 error "failed to set default LMV"
26081         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26082         (( max_inherit == -1 )) ||
26083                 error "wrong max_inherit value $max_inherit"
26084
26085         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26086         $LFS setdirstripe -D -c -1 $testdir ||
26087                 error "failed to set default LMV"
26088         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26089         (( max_inherit > 0 )) ||
26090                 error "wrong max_inherit value $max_inherit"
26091
26092         # and the subdir will decrease the max_inherit by 1
26093         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26094         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26095         (( sub_max_inherit == max_inherit - 1)) ||
26096                 error "wrong max-inherit of subdir $sub_max_inherit"
26097
26098         # check specified --max-inherit and warning message
26099         stack_trap "rm -f $tmpfile"
26100         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26101                 error "failed to set default LMV"
26102         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26103         (( max_inherit == -1 )) ||
26104                 error "wrong max_inherit value $max_inherit"
26105
26106         # check the warning messages
26107         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26108                 error "failed to detect warning string"
26109         fi
26110 }
26111 run_test 413e "check default max-inherit value"
26112
26113 test_fs_dmv_inherit()
26114 {
26115         local testdir=$DIR/$tdir
26116
26117         local count
26118         local inherit
26119         local inherit_rr
26120
26121         for i in 1 2 3; do
26122                 mkdir $testdir || error "mkdir $testdir failed"
26123                 count=$($LFS getdirstripe -D -c $testdir)
26124                 (( count == 1 )) ||
26125                         error "$testdir default LMV count mismatch $count != 1"
26126                 inherit=$($LFS getdirstripe -D -X $testdir)
26127                 (( inherit == 3 - i )) ||
26128                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26129                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26130                 (( inherit_rr == 3 - i )) ||
26131                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26132                 testdir=$testdir/sub
26133         done
26134
26135         mkdir $testdir || error "mkdir $testdir failed"
26136         count=$($LFS getdirstripe -D -c $testdir)
26137         (( count == 0 )) ||
26138                 error "$testdir default LMV count not zero: $count"
26139 }
26140
26141 test_413f() {
26142         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26143
26144         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26145                 skip "Need server version at least 2.14.55"
26146
26147         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26148                 error "dump $DIR default LMV failed"
26149         stack_trap "setfattr --restore=$TMP/dmv.ea"
26150
26151         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26152                 error "set $DIR default LMV failed"
26153
26154         test_fs_dmv_inherit
26155 }
26156 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26157
26158 test_413g() {
26159         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26160
26161         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26162         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26163                 error "dump $DIR default LMV failed"
26164         stack_trap "setfattr --restore=$TMP/dmv.ea"
26165
26166         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26167                 error "set $DIR default LMV failed"
26168
26169         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26170                 error "mount $MOUNT2 failed"
26171         stack_trap "umount_client $MOUNT2"
26172
26173         local saved_DIR=$DIR
26174
26175         export DIR=$MOUNT2
26176
26177         stack_trap "export DIR=$saved_DIR"
26178
26179         # first check filesystem-wide default LMV inheritance
26180         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26181
26182         # then check subdirs are spread to all MDTs
26183         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26184
26185         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26186
26187         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26188 }
26189 run_test 413g "enforce ROOT default LMV on subdir mount"
26190
26191 test_413h() {
26192         (( MDSCOUNT >= 2 )) ||
26193                 skip "We need at least 2 MDTs for this test"
26194
26195         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26196                 skip "Need server version at least 2.15.50.6"
26197
26198         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26199
26200         stack_trap "$LCTL set_param \
26201                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26202         $LCTL set_param lmv.*.qos_maxage=1
26203
26204         local depth=5
26205         local rr_depth=4
26206         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26207         local count=$((MDSCOUNT * 20))
26208
26209         generate_uneven_mdts 50
26210
26211         mkdir -p $dir || error "mkdir $dir failed"
26212         stack_trap "rm -rf $dir"
26213         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26214                 --max-inherit-rr=$rr_depth $dir
26215
26216         for ((d=0; d < depth + 2; d++)); do
26217                 log "dir=$dir:"
26218                 for ((sub=0; sub < count; sub++)); do
26219                         mkdir $dir/d$sub
26220                 done
26221                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26222                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26223                 # subdirs within $rr_depth should be created round-robin
26224                 if (( d < rr_depth )); then
26225                         (( ${num[0]} != count )) ||
26226                                 error "all objects created on MDT ${num[1]}"
26227                 fi
26228
26229                 dir=$dir/d0
26230         done
26231 }
26232 run_test 413h "don't stick to parent for round-robin dirs"
26233
26234 test_413z() {
26235         local pids=""
26236         local subdir
26237         local pid
26238
26239         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26240                 unlinkmany $subdir/f. $TEST413_COUNT &
26241                 pids="$pids $!"
26242         done
26243
26244         for pid in $pids; do
26245                 wait $pid
26246         done
26247 }
26248 run_test 413z "413 test cleanup"
26249
26250 test_414() {
26251 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26252         $LCTL set_param fail_loc=0x80000521
26253         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26254         rm -f $DIR/$tfile
26255 }
26256 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26257
26258 test_415() {
26259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26260         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26261                 skip "Need server version at least 2.11.52"
26262
26263         # LU-11102
26264         local total
26265         local setattr_pid
26266         local start_time
26267         local end_time
26268         local duration
26269
26270         total=500
26271         # this test may be slow on ZFS
26272         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26273
26274         # though this test is designed for striped directory, let's test normal
26275         # directory too since lock is always saved as CoS lock.
26276         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26277         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26278
26279         (
26280                 while true; do
26281                         touch $DIR/$tdir
26282                 done
26283         ) &
26284         setattr_pid=$!
26285
26286         start_time=$(date +%s)
26287         for i in $(seq $total); do
26288                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26289                         > /dev/null
26290         done
26291         end_time=$(date +%s)
26292         duration=$((end_time - start_time))
26293
26294         kill -9 $setattr_pid
26295
26296         echo "rename $total files took $duration sec"
26297         [ $duration -lt 100 ] || error "rename took $duration sec"
26298 }
26299 run_test 415 "lock revoke is not missing"
26300
26301 test_416() {
26302         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26303                 skip "Need server version at least 2.11.55"
26304
26305         # define OBD_FAIL_OSD_TXN_START    0x19a
26306         do_facet mds1 lctl set_param fail_loc=0x19a
26307
26308         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26309
26310         true
26311 }
26312 run_test 416 "transaction start failure won't cause system hung"
26313
26314 cleanup_417() {
26315         trap 0
26316         do_nodes $(comma_list $(mdts_nodes)) \
26317                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26318         do_nodes $(comma_list $(mdts_nodes)) \
26319                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26320         do_nodes $(comma_list $(mdts_nodes)) \
26321                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26322 }
26323
26324 test_417() {
26325         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26326         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26327                 skip "Need MDS version at least 2.11.56"
26328
26329         trap cleanup_417 RETURN EXIT
26330
26331         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26332         do_nodes $(comma_list $(mdts_nodes)) \
26333                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26334         $LFS migrate -m 0 $DIR/$tdir.1 &&
26335                 error "migrate dir $tdir.1 should fail"
26336
26337         do_nodes $(comma_list $(mdts_nodes)) \
26338                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26339         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26340                 error "create remote dir $tdir.2 should fail"
26341
26342         do_nodes $(comma_list $(mdts_nodes)) \
26343                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26344         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26345                 error "create striped dir $tdir.3 should fail"
26346         true
26347 }
26348 run_test 417 "disable remote dir, striped dir and dir migration"
26349
26350 # Checks that the outputs of df [-i] and lfs df [-i] match
26351 #
26352 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26353 check_lfs_df() {
26354         local dir=$2
26355         local inodes
26356         local df_out
26357         local lfs_df_out
26358         local count
26359         local passed=false
26360
26361         # blocks or inodes
26362         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26363
26364         for count in {1..100}; do
26365                 do_nodes "$CLIENTS" \
26366                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26367                 sync; sleep 0.2
26368
26369                 # read the lines of interest
26370                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26371                         error "df $inodes $dir | tail -n +2 failed"
26372                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26373                         error "lfs df $inodes $dir | grep summary: failed"
26374
26375                 # skip first substrings of each output as they are different
26376                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26377                 # compare the two outputs
26378                 passed=true
26379                 #  skip "available" on MDT until LU-13997 is fixed.
26380                 #for i in {1..5}; do
26381                 for i in 1 2 4 5; do
26382                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26383                 done
26384                 $passed && break
26385         done
26386
26387         if ! $passed; then
26388                 df -P $inodes $dir
26389                 echo
26390                 lfs df $inodes $dir
26391                 error "df and lfs df $1 output mismatch: "      \
26392                       "df ${inodes}: ${df_out[*]}, "            \
26393                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26394         fi
26395 }
26396
26397 test_418() {
26398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26399
26400         local dir=$DIR/$tdir
26401         local numfiles=$((RANDOM % 4096 + 2))
26402         local numblocks=$((RANDOM % 256 + 1))
26403
26404         wait_delete_completed
26405         test_mkdir $dir
26406
26407         # check block output
26408         check_lfs_df blocks $dir
26409         # check inode output
26410         check_lfs_df inodes $dir
26411
26412         # create a single file and retest
26413         echo "Creating a single file and testing"
26414         createmany -o $dir/$tfile- 1 &>/dev/null ||
26415                 error "creating 1 file in $dir failed"
26416         check_lfs_df blocks $dir
26417         check_lfs_df inodes $dir
26418
26419         # create a random number of files
26420         echo "Creating $((numfiles - 1)) files and testing"
26421         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26422                 error "creating $((numfiles - 1)) files in $dir failed"
26423
26424         # write a random number of blocks to the first test file
26425         echo "Writing $numblocks 4K blocks and testing"
26426         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26427                 count=$numblocks &>/dev/null ||
26428                 error "dd to $dir/${tfile}-0 failed"
26429
26430         # retest
26431         check_lfs_df blocks $dir
26432         check_lfs_df inodes $dir
26433
26434         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26435                 error "unlinking $numfiles files in $dir failed"
26436 }
26437 run_test 418 "df and lfs df outputs match"
26438
26439 test_419()
26440 {
26441         local dir=$DIR/$tdir
26442
26443         mkdir -p $dir
26444         touch $dir/file
26445
26446         cancel_lru_locks mdc
26447
26448         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26449         $LCTL set_param fail_loc=0x1410
26450         cat $dir/file
26451         $LCTL set_param fail_loc=0
26452         rm -rf $dir
26453 }
26454 run_test 419 "Verify open file by name doesn't crash kernel"
26455
26456 test_420()
26457 {
26458         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26459                 skip "Need MDS version at least 2.12.53"
26460
26461         local SAVE_UMASK=$(umask)
26462         local dir=$DIR/$tdir
26463         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26464
26465         mkdir -p $dir
26466         umask 0000
26467         mkdir -m03777 $dir/testdir
26468         ls -dn $dir/testdir
26469         # Need to remove trailing '.' when SELinux is enabled
26470         local dirperms=$(ls -dn $dir/testdir |
26471                          awk '{ sub(/\.$/, "", $1); print $1}')
26472         [ $dirperms == "drwxrwsrwt" ] ||
26473                 error "incorrect perms on $dir/testdir"
26474
26475         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26476                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26477         ls -n $dir/testdir/testfile
26478         local fileperms=$(ls -n $dir/testdir/testfile |
26479                           awk '{ sub(/\.$/, "", $1); print $1}')
26480         [ $fileperms == "-rwxr-xr-x" ] ||
26481                 error "incorrect perms on $dir/testdir/testfile"
26482
26483         umask $SAVE_UMASK
26484 }
26485 run_test 420 "clear SGID bit on non-directories for non-members"
26486
26487 test_421a() {
26488         local cnt
26489         local fid1
26490         local fid2
26491
26492         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26493                 skip "Need MDS version at least 2.12.54"
26494
26495         test_mkdir $DIR/$tdir
26496         createmany -o $DIR/$tdir/f 3
26497         cnt=$(ls -1 $DIR/$tdir | wc -l)
26498         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26499
26500         fid1=$(lfs path2fid $DIR/$tdir/f1)
26501         fid2=$(lfs path2fid $DIR/$tdir/f2)
26502         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26503
26504         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26505         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26506
26507         cnt=$(ls -1 $DIR/$tdir | wc -l)
26508         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26509
26510         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26511         createmany -o $DIR/$tdir/f 3
26512         cnt=$(ls -1 $DIR/$tdir | wc -l)
26513         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26514
26515         fid1=$(lfs path2fid $DIR/$tdir/f1)
26516         fid2=$(lfs path2fid $DIR/$tdir/f2)
26517         echo "remove using fsname $FSNAME"
26518         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26519
26520         cnt=$(ls -1 $DIR/$tdir | wc -l)
26521         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26522 }
26523 run_test 421a "simple rm by fid"
26524
26525 test_421b() {
26526         local cnt
26527         local FID1
26528         local FID2
26529
26530         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26531                 skip "Need MDS version at least 2.12.54"
26532
26533         test_mkdir $DIR/$tdir
26534         createmany -o $DIR/$tdir/f 3
26535         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26536         MULTIPID=$!
26537
26538         FID1=$(lfs path2fid $DIR/$tdir/f1)
26539         FID2=$(lfs path2fid $DIR/$tdir/f2)
26540         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26541
26542         kill -USR1 $MULTIPID
26543         wait
26544
26545         cnt=$(ls $DIR/$tdir | wc -l)
26546         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26547 }
26548 run_test 421b "rm by fid on open file"
26549
26550 test_421c() {
26551         local cnt
26552         local FIDS
26553
26554         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26555                 skip "Need MDS version at least 2.12.54"
26556
26557         test_mkdir $DIR/$tdir
26558         createmany -o $DIR/$tdir/f 3
26559         touch $DIR/$tdir/$tfile
26560         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26561         cnt=$(ls -1 $DIR/$tdir | wc -l)
26562         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26563
26564         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26565         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26566
26567         cnt=$(ls $DIR/$tdir | wc -l)
26568         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26569 }
26570 run_test 421c "rm by fid against hardlinked files"
26571
26572 test_421d() {
26573         local cnt
26574         local FIDS
26575
26576         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26577                 skip "Need MDS version at least 2.12.54"
26578
26579         test_mkdir $DIR/$tdir
26580         createmany -o $DIR/$tdir/f 4097
26581         cnt=$(ls -1 $DIR/$tdir | wc -l)
26582         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26583
26584         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26585         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26586
26587         cnt=$(ls $DIR/$tdir | wc -l)
26588         rm -rf $DIR/$tdir
26589         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26590 }
26591 run_test 421d "rmfid en masse"
26592
26593 test_421e() {
26594         local cnt
26595         local FID
26596
26597         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26598         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26599                 skip "Need MDS version at least 2.12.54"
26600
26601         mkdir -p $DIR/$tdir
26602         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26603         createmany -o $DIR/$tdir/striped_dir/f 512
26604         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26605         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26606
26607         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26608                 sed "s/[/][^:]*://g")
26609         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26610
26611         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26612         rm -rf $DIR/$tdir
26613         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26614 }
26615 run_test 421e "rmfid in DNE"
26616
26617 test_421f() {
26618         local cnt
26619         local FID
26620
26621         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26622                 skip "Need MDS version at least 2.12.54"
26623
26624         test_mkdir $DIR/$tdir
26625         touch $DIR/$tdir/f
26626         cnt=$(ls -1 $DIR/$tdir | wc -l)
26627         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26628
26629         FID=$(lfs path2fid $DIR/$tdir/f)
26630         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26631         # rmfid should fail
26632         cnt=$(ls -1 $DIR/$tdir | wc -l)
26633         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26634
26635         chmod a+rw $DIR/$tdir
26636         ls -la $DIR/$tdir
26637         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26638         # rmfid should fail
26639         cnt=$(ls -1 $DIR/$tdir | wc -l)
26640         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26641
26642         rm -f $DIR/$tdir/f
26643         $RUNAS touch $DIR/$tdir/f
26644         FID=$(lfs path2fid $DIR/$tdir/f)
26645         echo "rmfid as root"
26646         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26647         cnt=$(ls -1 $DIR/$tdir | wc -l)
26648         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26649
26650         rm -f $DIR/$tdir/f
26651         $RUNAS touch $DIR/$tdir/f
26652         cnt=$(ls -1 $DIR/$tdir | wc -l)
26653         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26654         FID=$(lfs path2fid $DIR/$tdir/f)
26655         # rmfid w/o user_fid2path mount option should fail
26656         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26657         cnt=$(ls -1 $DIR/$tdir | wc -l)
26658         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26659
26660         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26661         stack_trap "rmdir $tmpdir"
26662         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26663                 error "failed to mount client'"
26664         stack_trap "umount_client $tmpdir"
26665
26666         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26667         # rmfid should succeed
26668         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26669         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26670
26671         # rmfid shouldn't allow to remove files due to dir's permission
26672         chmod a+rwx $tmpdir/$tdir
26673         touch $tmpdir/$tdir/f
26674         ls -la $tmpdir/$tdir
26675         FID=$(lfs path2fid $tmpdir/$tdir/f)
26676         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26677         return 0
26678 }
26679 run_test 421f "rmfid checks permissions"
26680
26681 test_421g() {
26682         local cnt
26683         local FIDS
26684
26685         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26686         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26687                 skip "Need MDS version at least 2.12.54"
26688
26689         mkdir -p $DIR/$tdir
26690         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26691         createmany -o $DIR/$tdir/striped_dir/f 512
26692         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26693         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26694
26695         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26696                 sed "s/[/][^:]*://g")
26697
26698         rm -f $DIR/$tdir/striped_dir/f1*
26699         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26700         removed=$((512 - cnt))
26701
26702         # few files have been just removed, so we expect
26703         # rmfid to fail on their fids
26704         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26705         [ $removed != $errors ] && error "$errors != $removed"
26706
26707         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26708         rm -rf $DIR/$tdir
26709         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26710 }
26711 run_test 421g "rmfid to return errors properly"
26712
26713 test_422() {
26714         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26715         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26716         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26717         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26718         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26719
26720         local amc=$(at_max_get client)
26721         local amo=$(at_max_get mds1)
26722         local timeout=`lctl get_param -n timeout`
26723
26724         at_max_set 0 client
26725         at_max_set 0 mds1
26726
26727 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26728         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26729                         fail_val=$(((2*timeout + 10)*1000))
26730         touch $DIR/$tdir/d3/file &
26731         sleep 2
26732 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26733         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26734                         fail_val=$((2*timeout + 5))
26735         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26736         local pid=$!
26737         sleep 1
26738         kill -9 $pid
26739         sleep $((2 * timeout))
26740         echo kill $pid
26741         kill -9 $pid
26742         lctl mark touch
26743         touch $DIR/$tdir/d2/file3
26744         touch $DIR/$tdir/d2/file4
26745         touch $DIR/$tdir/d2/file5
26746
26747         wait
26748         at_max_set $amc client
26749         at_max_set $amo mds1
26750
26751         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26752         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26753                 error "Watchdog is always throttled"
26754 }
26755 run_test 422 "kill a process with RPC in progress"
26756
26757 stat_test() {
26758     df -h $MOUNT &
26759     df -h $MOUNT &
26760     df -h $MOUNT &
26761     df -h $MOUNT &
26762     df -h $MOUNT &
26763     df -h $MOUNT &
26764 }
26765
26766 test_423() {
26767     local _stats
26768     # ensure statfs cache is expired
26769     sleep 2;
26770
26771     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26772     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26773
26774     return 0
26775 }
26776 run_test 423 "statfs should return a right data"
26777
26778 test_424() {
26779 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26780         $LCTL set_param fail_loc=0x80000522
26781         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26782         rm -f $DIR/$tfile
26783 }
26784 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26785
26786 test_425() {
26787         test_mkdir -c -1 $DIR/$tdir
26788         $LFS setstripe -c -1 $DIR/$tdir
26789
26790         lru_resize_disable "" 100
26791         stack_trap "lru_resize_enable" EXIT
26792
26793         sleep 5
26794
26795         for i in $(seq $((MDSCOUNT * 125))); do
26796                 local t=$DIR/$tdir/$tfile_$i
26797
26798                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26799                         error_noexit "Create file $t"
26800         done
26801         stack_trap "rm -rf $DIR/$tdir" EXIT
26802
26803         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26804                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26805                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26806
26807                 [ $lock_count -le $lru_size ] ||
26808                         error "osc lock count $lock_count > lru size $lru_size"
26809         done
26810
26811         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26812                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26813                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26814
26815                 [ $lock_count -le $lru_size ] ||
26816                         error "mdc lock count $lock_count > lru size $lru_size"
26817         done
26818 }
26819 run_test 425 "lock count should not exceed lru size"
26820
26821 test_426() {
26822         splice-test -r $DIR/$tfile
26823         splice-test -rd $DIR/$tfile
26824         splice-test $DIR/$tfile
26825         splice-test -d $DIR/$tfile
26826 }
26827 run_test 426 "splice test on Lustre"
26828
26829 test_427() {
26830         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26831         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26832                 skip "Need MDS version at least 2.12.4"
26833         local log
26834
26835         mkdir $DIR/$tdir
26836         mkdir $DIR/$tdir/1
26837         mkdir $DIR/$tdir/2
26838         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26839         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26840
26841         $LFS getdirstripe $DIR/$tdir/1/dir
26842
26843         #first setfattr for creating updatelog
26844         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26845
26846 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26847         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26848         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26849         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26850
26851         sleep 2
26852         fail mds2
26853         wait_recovery_complete mds2 $((2*TIMEOUT))
26854
26855         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26856         echo $log | grep "get update log failed" &&
26857                 error "update log corruption is detected" || true
26858 }
26859 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26860
26861 test_428() {
26862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26863         local cache_limit=$CACHE_MAX
26864
26865         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26866         $LCTL set_param -n llite.*.max_cached_mb=64
26867
26868         mkdir $DIR/$tdir
26869         $LFS setstripe -c 1 $DIR/$tdir
26870         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26871         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26872         #test write
26873         for f in $(seq 4); do
26874                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26875         done
26876         wait
26877
26878         cancel_lru_locks osc
26879         # Test read
26880         for f in $(seq 4); do
26881                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26882         done
26883         wait
26884 }
26885 run_test 428 "large block size IO should not hang"
26886
26887 test_429() { # LU-7915 / LU-10948
26888         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26889         local testfile=$DIR/$tfile
26890         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26891         local new_flag=1
26892         local first_rpc
26893         local second_rpc
26894         local third_rpc
26895
26896         $LCTL get_param $ll_opencache_threshold_count ||
26897                 skip "client does not have opencache parameter"
26898
26899         set_opencache $new_flag
26900         stack_trap "restore_opencache"
26901         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26902                 error "enable opencache failed"
26903         touch $testfile
26904         # drop MDC DLM locks
26905         cancel_lru_locks mdc
26906         # clear MDC RPC stats counters
26907         $LCTL set_param $mdc_rpcstats=clear
26908
26909         # According to the current implementation, we need to run 3 times
26910         # open & close file to verify if opencache is enabled correctly.
26911         # 1st, RPCs are sent for lookup/open and open handle is released on
26912         #      close finally.
26913         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26914         #      so open handle won't be released thereafter.
26915         # 3rd, No RPC is sent out.
26916         $MULTIOP $testfile oc || error "multiop failed"
26917         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26918         echo "1st: $first_rpc RPCs in flight"
26919
26920         $MULTIOP $testfile oc || error "multiop failed"
26921         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26922         echo "2nd: $second_rpc RPCs in flight"
26923
26924         $MULTIOP $testfile oc || error "multiop failed"
26925         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26926         echo "3rd: $third_rpc RPCs in flight"
26927
26928         #verify no MDC RPC is sent
26929         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26930 }
26931 run_test 429 "verify if opencache flag on client side does work"
26932
26933 lseek_test_430() {
26934         local offset
26935         local file=$1
26936
26937         # data at [200K, 400K)
26938         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26939                 error "256K->512K dd fails"
26940         # data at [2M, 3M)
26941         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26942                 error "2M->3M dd fails"
26943         # data at [4M, 5M)
26944         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26945                 error "4M->5M dd fails"
26946         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26947         # start at first component hole #1
26948         printf "Seeking hole from 1000 ... "
26949         offset=$(lseek_test -l 1000 $file)
26950         echo $offset
26951         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26952         printf "Seeking data from 1000 ... "
26953         offset=$(lseek_test -d 1000 $file)
26954         echo $offset
26955         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26956
26957         # start at first component data block
26958         printf "Seeking hole from 300000 ... "
26959         offset=$(lseek_test -l 300000 $file)
26960         echo $offset
26961         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26962         printf "Seeking data from 300000 ... "
26963         offset=$(lseek_test -d 300000 $file)
26964         echo $offset
26965         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26966
26967         # start at the first component but beyond end of object size
26968         printf "Seeking hole from 1000000 ... "
26969         offset=$(lseek_test -l 1000000 $file)
26970         echo $offset
26971         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26972         printf "Seeking data from 1000000 ... "
26973         offset=$(lseek_test -d 1000000 $file)
26974         echo $offset
26975         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26976
26977         # start at second component stripe 2 (empty file)
26978         printf "Seeking hole from 1500000 ... "
26979         offset=$(lseek_test -l 1500000 $file)
26980         echo $offset
26981         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26982         printf "Seeking data from 1500000 ... "
26983         offset=$(lseek_test -d 1500000 $file)
26984         echo $offset
26985         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26986
26987         # start at second component stripe 1 (all data)
26988         printf "Seeking hole from 3000000 ... "
26989         offset=$(lseek_test -l 3000000 $file)
26990         echo $offset
26991         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26992         printf "Seeking data from 3000000 ... "
26993         offset=$(lseek_test -d 3000000 $file)
26994         echo $offset
26995         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26996
26997         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26998                 error "2nd dd fails"
26999         echo "Add data block at 640K...1280K"
27000
27001         # start at before new data block, in hole
27002         printf "Seeking hole from 600000 ... "
27003         offset=$(lseek_test -l 600000 $file)
27004         echo $offset
27005         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27006         printf "Seeking data from 600000 ... "
27007         offset=$(lseek_test -d 600000 $file)
27008         echo $offset
27009         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27010
27011         # start at the first component new data block
27012         printf "Seeking hole from 1000000 ... "
27013         offset=$(lseek_test -l 1000000 $file)
27014         echo $offset
27015         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27016         printf "Seeking data from 1000000 ... "
27017         offset=$(lseek_test -d 1000000 $file)
27018         echo $offset
27019         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27020
27021         # start at second component stripe 2, new data
27022         printf "Seeking hole from 1200000 ... "
27023         offset=$(lseek_test -l 1200000 $file)
27024         echo $offset
27025         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27026         printf "Seeking data from 1200000 ... "
27027         offset=$(lseek_test -d 1200000 $file)
27028         echo $offset
27029         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27030
27031         # start beyond file end
27032         printf "Using offset > filesize ... "
27033         lseek_test -l 4000000 $file && error "lseek should fail"
27034         printf "Using offset > filesize ... "
27035         lseek_test -d 4000000 $file && error "lseek should fail"
27036
27037         printf "Done\n\n"
27038 }
27039
27040 test_430a() {
27041         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27042                 skip "MDT does not support SEEK_HOLE"
27043
27044         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27045                 skip "OST does not support SEEK_HOLE"
27046
27047         local file=$DIR/$tdir/$tfile
27048
27049         mkdir -p $DIR/$tdir
27050
27051         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27052         # OST stripe #1 will have continuous data at [1M, 3M)
27053         # OST stripe #2 is empty
27054         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27055         lseek_test_430 $file
27056         rm $file
27057         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27058         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27059         lseek_test_430 $file
27060         rm $file
27061         $LFS setstripe -c2 -S 512K $file
27062         echo "Two stripes, stripe size 512K"
27063         lseek_test_430 $file
27064         rm $file
27065         # FLR with stale mirror
27066         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27067                        -N -c2 -S 1M $file
27068         echo "Mirrored file:"
27069         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27070         echo "Plain 2 stripes 1M"
27071         lseek_test_430 $file
27072         rm $file
27073 }
27074 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27075
27076 test_430b() {
27077         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27078                 skip "OST does not support SEEK_HOLE"
27079
27080         local offset
27081         local file=$DIR/$tdir/$tfile
27082
27083         mkdir -p $DIR/$tdir
27084         # Empty layout lseek should fail
27085         $MCREATE $file
27086         # seek from 0
27087         printf "Seeking hole from 0 ... "
27088         lseek_test -l 0 $file && error "lseek should fail"
27089         printf "Seeking data from 0 ... "
27090         lseek_test -d 0 $file && error "lseek should fail"
27091         rm $file
27092
27093         # 1M-hole file
27094         $LFS setstripe -E 1M -c2 -E eof $file
27095         $TRUNCATE $file 1048576
27096         printf "Seeking hole from 1000000 ... "
27097         offset=$(lseek_test -l 1000000 $file)
27098         echo $offset
27099         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27100         printf "Seeking data from 1000000 ... "
27101         lseek_test -d 1000000 $file && error "lseek should fail"
27102         rm $file
27103
27104         # full component followed by non-inited one
27105         $LFS setstripe -E 1M -c2 -E eof $file
27106         dd if=/dev/urandom of=$file bs=1M count=1
27107         printf "Seeking hole from 1000000 ... "
27108         offset=$(lseek_test -l 1000000 $file)
27109         echo $offset
27110         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27111         printf "Seeking hole from 1048576 ... "
27112         lseek_test -l 1048576 $file && error "lseek should fail"
27113         # init second component and truncate back
27114         echo "123" >> $file
27115         $TRUNCATE $file 1048576
27116         printf "Seeking hole from 1000000 ... "
27117         offset=$(lseek_test -l 1000000 $file)
27118         echo $offset
27119         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27120         printf "Seeking hole from 1048576 ... "
27121         lseek_test -l 1048576 $file && error "lseek should fail"
27122         # boundary checks for big values
27123         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27124         offset=$(lseek_test -d 0 $file.10g)
27125         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27126         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27127         offset=$(lseek_test -d 0 $file.100g)
27128         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27129         return 0
27130 }
27131 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27132
27133 test_430c() {
27134         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27135                 skip "OST does not support SEEK_HOLE"
27136
27137         local file=$DIR/$tdir/$tfile
27138         local start
27139
27140         mkdir -p $DIR/$tdir
27141         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27142
27143         # cp version 8.33+ prefers lseek over fiemap
27144         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27145                 start=$SECONDS
27146                 time cp $file /dev/null
27147                 (( SECONDS - start < 5 )) ||
27148                         error "cp: too long runtime $((SECONDS - start))"
27149
27150         fi
27151         # tar version 1.29+ supports SEEK_HOLE/DATA
27152         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27153                 start=$SECONDS
27154                 time tar cS $file - | cat > /dev/null
27155                 (( SECONDS - start < 5 )) ||
27156                         error "tar: too long runtime $((SECONDS - start))"
27157         fi
27158 }
27159 run_test 430c "lseek: external tools check"
27160
27161 test_431() { # LU-14187
27162         local file=$DIR/$tdir/$tfile
27163
27164         mkdir -p $DIR/$tdir
27165         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27166         dd if=/dev/urandom of=$file bs=4k count=1
27167         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27168         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27169         #define OBD_FAIL_OST_RESTART_IO 0x251
27170         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27171         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27172         cp $file $file.0
27173         cancel_lru_locks
27174         sync_all_data
27175         echo 3 > /proc/sys/vm/drop_caches
27176         diff  $file $file.0 || error "data diff"
27177 }
27178 run_test 431 "Restart transaction for IO"
27179
27180 cleanup_test_432() {
27181         do_facet mgs $LCTL nodemap_activate 0
27182         wait_nm_sync active
27183 }
27184
27185 test_432() {
27186         local tmpdir=$TMP/dir432
27187
27188         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27189                 skip "Need MDS version at least 2.14.52"
27190
27191         stack_trap cleanup_test_432 EXIT
27192         mkdir $DIR/$tdir
27193         mkdir $tmpdir
27194
27195         do_facet mgs $LCTL nodemap_activate 1
27196         wait_nm_sync active
27197         do_facet mgs $LCTL nodemap_modify --name default \
27198                 --property admin --value 1
27199         do_facet mgs $LCTL nodemap_modify --name default \
27200                 --property trusted --value 1
27201         cancel_lru_locks mdc
27202         wait_nm_sync default admin_nodemap
27203         wait_nm_sync default trusted_nodemap
27204
27205         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27206                grep -ci "Operation not permitted") -ne 0 ]; then
27207                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27208         fi
27209 }
27210 run_test 432 "mv dir from outside Lustre"
27211
27212 test_433() {
27213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27214
27215         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27216                 skip "inode cache not supported"
27217
27218         $LCTL set_param llite.*.inode_cache=0
27219         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27220
27221         local count=256
27222         local before
27223         local after
27224
27225         cancel_lru_locks mdc
27226         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27227         createmany -m $DIR/$tdir/f $count
27228         createmany -d $DIR/$tdir/d $count
27229         ls -l $DIR/$tdir > /dev/null
27230         stack_trap "rm -rf $DIR/$tdir"
27231
27232         before=$(num_objects)
27233         cancel_lru_locks mdc
27234         after=$(num_objects)
27235
27236         # sometimes even @before is less than 2 * count
27237         while (( before - after < count )); do
27238                 sleep 1
27239                 after=$(num_objects)
27240                 wait=$((wait + 1))
27241                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27242                 if (( wait > 60 )); then
27243                         error "inode slab grew from $before to $after"
27244                 fi
27245         done
27246
27247         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27248 }
27249 run_test 433 "ldlm lock cancel releases dentries and inodes"
27250
27251 prep_801() {
27252         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27253         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27254                 skip "Need server version at least 2.9.55"
27255
27256         start_full_debug_logging
27257 }
27258
27259 post_801() {
27260         stop_full_debug_logging
27261 }
27262
27263 barrier_stat() {
27264         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27265                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27266                            awk '/The barrier for/ { print $7 }')
27267                 echo $st
27268         else
27269                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27270                 echo \'$st\'
27271         fi
27272 }
27273
27274 barrier_expired() {
27275         local expired
27276
27277         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27278                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27279                           awk '/will be expired/ { print $7 }')
27280         else
27281                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27282         fi
27283
27284         echo $expired
27285 }
27286
27287 test_801a() {
27288         prep_801
27289
27290         echo "Start barrier_freeze at: $(date)"
27291         #define OBD_FAIL_BARRIER_DELAY          0x2202
27292         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27293         # Do not reduce barrier time - See LU-11873
27294         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27295
27296         sleep 2
27297         local b_status=$(barrier_stat)
27298         echo "Got barrier status at: $(date)"
27299         [ "$b_status" = "'freezing_p1'" ] ||
27300                 error "(1) unexpected barrier status $b_status"
27301
27302         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27303         wait
27304         b_status=$(barrier_stat)
27305         [ "$b_status" = "'frozen'" ] ||
27306                 error "(2) unexpected barrier status $b_status"
27307
27308         local expired=$(barrier_expired)
27309         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27310         sleep $((expired + 3))
27311
27312         b_status=$(barrier_stat)
27313         [ "$b_status" = "'expired'" ] ||
27314                 error "(3) unexpected barrier status $b_status"
27315
27316         # Do not reduce barrier time - See LU-11873
27317         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27318                 error "(4) fail to freeze barrier"
27319
27320         b_status=$(barrier_stat)
27321         [ "$b_status" = "'frozen'" ] ||
27322                 error "(5) unexpected barrier status $b_status"
27323
27324         echo "Start barrier_thaw at: $(date)"
27325         #define OBD_FAIL_BARRIER_DELAY          0x2202
27326         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27327         do_facet mgs $LCTL barrier_thaw $FSNAME &
27328
27329         sleep 2
27330         b_status=$(barrier_stat)
27331         echo "Got barrier status at: $(date)"
27332         [ "$b_status" = "'thawing'" ] ||
27333                 error "(6) unexpected barrier status $b_status"
27334
27335         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27336         wait
27337         b_status=$(barrier_stat)
27338         [ "$b_status" = "'thawed'" ] ||
27339                 error "(7) unexpected barrier status $b_status"
27340
27341         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27342         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27343         do_facet mgs $LCTL barrier_freeze $FSNAME
27344
27345         b_status=$(barrier_stat)
27346         [ "$b_status" = "'failed'" ] ||
27347                 error "(8) unexpected barrier status $b_status"
27348
27349         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27350         do_facet mgs $LCTL barrier_thaw $FSNAME
27351
27352         post_801
27353 }
27354 run_test 801a "write barrier user interfaces and stat machine"
27355
27356 test_801b() {
27357         prep_801
27358
27359         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27360         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27361         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27362         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27363         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27364
27365         cancel_lru_locks mdc
27366
27367         # 180 seconds should be long enough
27368         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27369
27370         local b_status=$(barrier_stat)
27371         [ "$b_status" = "'frozen'" ] ||
27372                 error "(6) unexpected barrier status $b_status"
27373
27374         mkdir $DIR/$tdir/d0/d10 &
27375         mkdir_pid=$!
27376
27377         touch $DIR/$tdir/d1/f13 &
27378         touch_pid=$!
27379
27380         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27381         ln_pid=$!
27382
27383         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27384         mv_pid=$!
27385
27386         rm -f $DIR/$tdir/d4/f12 &
27387         rm_pid=$!
27388
27389         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27390
27391         # To guarantee taht the 'stat' is not blocked
27392         b_status=$(barrier_stat)
27393         [ "$b_status" = "'frozen'" ] ||
27394                 error "(8) unexpected barrier status $b_status"
27395
27396         # let above commands to run at background
27397         sleep 5
27398
27399         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27400         ps -p $touch_pid || error "(10) touch should be blocked"
27401         ps -p $ln_pid || error "(11) link should be blocked"
27402         ps -p $mv_pid || error "(12) rename should be blocked"
27403         ps -p $rm_pid || error "(13) unlink should be blocked"
27404
27405         b_status=$(barrier_stat)
27406         [ "$b_status" = "'frozen'" ] ||
27407                 error "(14) unexpected barrier status $b_status"
27408
27409         do_facet mgs $LCTL barrier_thaw $FSNAME
27410         b_status=$(barrier_stat)
27411         [ "$b_status" = "'thawed'" ] ||
27412                 error "(15) unexpected barrier status $b_status"
27413
27414         wait $mkdir_pid || error "(16) mkdir should succeed"
27415         wait $touch_pid || error "(17) touch should succeed"
27416         wait $ln_pid || error "(18) link should succeed"
27417         wait $mv_pid || error "(19) rename should succeed"
27418         wait $rm_pid || error "(20) unlink should succeed"
27419
27420         post_801
27421 }
27422 run_test 801b "modification will be blocked by write barrier"
27423
27424 test_801c() {
27425         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27426
27427         prep_801
27428
27429         stop mds2 || error "(1) Fail to stop mds2"
27430
27431         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27432
27433         local b_status=$(barrier_stat)
27434         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27435                 do_facet mgs $LCTL barrier_thaw $FSNAME
27436                 error "(2) unexpected barrier status $b_status"
27437         }
27438
27439         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27440                 error "(3) Fail to rescan barrier bitmap"
27441
27442         # Do not reduce barrier time - See LU-11873
27443         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27444
27445         b_status=$(barrier_stat)
27446         [ "$b_status" = "'frozen'" ] ||
27447                 error "(4) unexpected barrier status $b_status"
27448
27449         do_facet mgs $LCTL barrier_thaw $FSNAME
27450         b_status=$(barrier_stat)
27451         [ "$b_status" = "'thawed'" ] ||
27452                 error "(5) unexpected barrier status $b_status"
27453
27454         local devname=$(mdsdevname 2)
27455
27456         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27457
27458         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27459                 error "(7) Fail to rescan barrier bitmap"
27460
27461         post_801
27462 }
27463 run_test 801c "rescan barrier bitmap"
27464
27465 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27466 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27467 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27468 saved_MOUNT_OPTS=$MOUNT_OPTS
27469
27470 cleanup_802a() {
27471         trap 0
27472
27473         stopall
27474         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27475         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27476         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27477         MOUNT_OPTS=$saved_MOUNT_OPTS
27478         setupall
27479 }
27480
27481 test_802a() {
27482         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27483         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27484         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27485                 skip "Need server version at least 2.9.55"
27486
27487         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27488
27489         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27490
27491         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27492                 error "(2) Fail to copy"
27493
27494         trap cleanup_802a EXIT
27495
27496         # sync by force before remount as readonly
27497         sync; sync_all_data; sleep 3; sync_all_data
27498
27499         stopall
27500
27501         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27502         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27503         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27504
27505         echo "Mount the server as read only"
27506         setupall server_only || error "(3) Fail to start servers"
27507
27508         echo "Mount client without ro should fail"
27509         mount_client $MOUNT &&
27510                 error "(4) Mount client without 'ro' should fail"
27511
27512         echo "Mount client with ro should succeed"
27513         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27514         mount_client $MOUNT ||
27515                 error "(5) Mount client with 'ro' should succeed"
27516
27517         echo "Modify should be refused"
27518         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27519
27520         echo "Read should be allowed"
27521         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27522                 error "(7) Read should succeed under ro mode"
27523
27524         cleanup_802a
27525 }
27526 run_test 802a "simulate readonly device"
27527
27528 test_802b() {
27529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27530         remote_mds_nodsh && skip "remote MDS with nodsh"
27531
27532         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27533                 skip "readonly option not available"
27534
27535         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27536
27537         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27538                 error "(2) Fail to copy"
27539
27540         # write back all cached data before setting MDT to readonly
27541         cancel_lru_locks
27542         sync_all_data
27543
27544         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27545         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27546
27547         echo "Modify should be refused"
27548         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27549
27550         echo "Read should be allowed"
27551         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27552                 error "(7) Read should succeed under ro mode"
27553
27554         # disable readonly
27555         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27556 }
27557 run_test 802b "be able to set MDTs to readonly"
27558
27559 test_803a() {
27560         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27561         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27562                 skip "MDS needs to be newer than 2.10.54"
27563
27564         mkdir_on_mdt0 $DIR/$tdir
27565         # Create some objects on all MDTs to trigger related logs objects
27566         for idx in $(seq $MDSCOUNT); do
27567                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27568                         $DIR/$tdir/dir${idx} ||
27569                         error "Fail to create $DIR/$tdir/dir${idx}"
27570         done
27571
27572         sync; sleep 3
27573         wait_delete_completed # ensure old test cleanups are finished
27574         echo "before create:"
27575         $LFS df -i $MOUNT
27576         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27577
27578         for i in {1..10}; do
27579                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27580                         error "Fail to create $DIR/$tdir/foo$i"
27581         done
27582
27583         sync; sleep 3
27584         echo "after create:"
27585         $LFS df -i $MOUNT
27586         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27587
27588         # allow for an llog to be cleaned up during the test
27589         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27590                 error "before ($before_used) + 10 > after ($after_used)"
27591
27592         for i in {1..10}; do
27593                 rm -rf $DIR/$tdir/foo$i ||
27594                         error "Fail to remove $DIR/$tdir/foo$i"
27595         done
27596
27597         sleep 3 # avoid MDT return cached statfs
27598         wait_delete_completed
27599         echo "after unlink:"
27600         $LFS df -i $MOUNT
27601         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27602
27603         # allow for an llog to be created during the test
27604         [ $after_used -le $((before_used + 1)) ] ||
27605                 error "after ($after_used) > before ($before_used) + 1"
27606 }
27607 run_test 803a "verify agent object for remote object"
27608
27609 test_803b() {
27610         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27611         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27612                 skip "MDS needs to be newer than 2.13.56"
27613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27614
27615         for i in $(seq 0 $((MDSCOUNT - 1))); do
27616                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27617         done
27618
27619         local before=0
27620         local after=0
27621
27622         local tmp
27623
27624         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27625         for i in $(seq 0 $((MDSCOUNT - 1))); do
27626                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27627                         awk '/getattr/ { print $2 }')
27628                 before=$((before + tmp))
27629         done
27630         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27631         for i in $(seq 0 $((MDSCOUNT - 1))); do
27632                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27633                         awk '/getattr/ { print $2 }')
27634                 after=$((after + tmp))
27635         done
27636
27637         [ $before -eq $after ] || error "getattr count $before != $after"
27638 }
27639 run_test 803b "remote object can getattr from cache"
27640
27641 test_804() {
27642         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27643         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27644                 skip "MDS needs to be newer than 2.10.54"
27645         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27646
27647         mkdir -p $DIR/$tdir
27648         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27649                 error "Fail to create $DIR/$tdir/dir0"
27650
27651         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27652         local dev=$(mdsdevname 2)
27653
27654         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27655                 grep ${fid} || error "NOT found agent entry for dir0"
27656
27657         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27658                 error "Fail to create $DIR/$tdir/dir1"
27659
27660         touch $DIR/$tdir/dir1/foo0 ||
27661                 error "Fail to create $DIR/$tdir/dir1/foo0"
27662         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27663         local rc=0
27664
27665         for idx in $(seq $MDSCOUNT); do
27666                 dev=$(mdsdevname $idx)
27667                 do_facet mds${idx} \
27668                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27669                         grep ${fid} && rc=$idx
27670         done
27671
27672         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27673                 error "Fail to rename foo0 to foo1"
27674         if [ $rc -eq 0 ]; then
27675                 for idx in $(seq $MDSCOUNT); do
27676                         dev=$(mdsdevname $idx)
27677                         do_facet mds${idx} \
27678                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27679                         grep ${fid} && rc=$idx
27680                 done
27681         fi
27682
27683         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27684                 error "Fail to rename foo1 to foo2"
27685         if [ $rc -eq 0 ]; then
27686                 for idx in $(seq $MDSCOUNT); do
27687                         dev=$(mdsdevname $idx)
27688                         do_facet mds${idx} \
27689                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27690                         grep ${fid} && rc=$idx
27691                 done
27692         fi
27693
27694         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27695
27696         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27697                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27698         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27699                 error "Fail to rename foo2 to foo0"
27700         unlink $DIR/$tdir/dir1/foo0 ||
27701                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27702         rm -rf $DIR/$tdir/dir0 ||
27703                 error "Fail to rm $DIR/$tdir/dir0"
27704
27705         for idx in $(seq $MDSCOUNT); do
27706                 rc=0
27707
27708                 stop mds${idx}
27709                 dev=$(mdsdevname $idx)
27710                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27711                         rc=$?
27712                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27713                         error "mount mds$idx failed"
27714                 df $MOUNT > /dev/null 2>&1
27715
27716                 # e2fsck should not return error
27717                 [ $rc -eq 0 ] ||
27718                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27719         done
27720 }
27721 run_test 804 "verify agent entry for remote entry"
27722
27723 cleanup_805() {
27724         do_facet $SINGLEMDS zfs set quota=$old $fsset
27725         unlinkmany $DIR/$tdir/f- 1000000
27726         trap 0
27727 }
27728
27729 test_805() {
27730         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27731         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27732         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27733                 skip "netfree not implemented before 0.7"
27734         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27735                 skip "Need MDS version at least 2.10.57"
27736
27737         local fsset
27738         local freekb
27739         local usedkb
27740         local old
27741         local quota
27742         local pref="osd-zfs.$FSNAME-MDT0000."
27743
27744         # limit available space on MDS dataset to meet nospace issue
27745         # quickly. then ZFS 0.7.2 can use reserved space if asked
27746         # properly (using netfree flag in osd_declare_destroy()
27747         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27748         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27749                 gawk '{print $3}')
27750         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27751         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27752         let "usedkb=usedkb-freekb"
27753         let "freekb=freekb/2"
27754         if let "freekb > 5000"; then
27755                 let "freekb=5000"
27756         fi
27757         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27758         trap cleanup_805 EXIT
27759         mkdir_on_mdt0 $DIR/$tdir
27760         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27761                 error "Can't set PFL layout"
27762         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27763         rm -rf $DIR/$tdir || error "not able to remove"
27764         do_facet $SINGLEMDS zfs set quota=$old $fsset
27765         trap 0
27766 }
27767 run_test 805 "ZFS can remove from full fs"
27768
27769 # Size-on-MDS test
27770 check_lsom_data()
27771 {
27772         local file=$1
27773         local expect=$(stat -c %s $file)
27774
27775         check_lsom_size $1 $expect
27776
27777         local blocks=$($LFS getsom -b $file)
27778         expect=$(stat -c %b $file)
27779         [[ $blocks == $expect ]] ||
27780                 error "$file expected blocks: $expect, got: $blocks"
27781 }
27782
27783 check_lsom_size()
27784 {
27785         local size
27786         local expect=$2
27787
27788         cancel_lru_locks mdc
27789
27790         size=$($LFS getsom -s $1)
27791         [[ $size == $expect ]] ||
27792                 error "$file expected size: $expect, got: $size"
27793 }
27794
27795 test_806() {
27796         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27797                 skip "Need MDS version at least 2.11.52"
27798
27799         local bs=1048576
27800
27801         touch $DIR/$tfile || error "touch $tfile failed"
27802
27803         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27804         save_lustre_params client "llite.*.xattr_cache" > $save
27805         lctl set_param llite.*.xattr_cache=0
27806         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27807
27808         # single-threaded write
27809         echo "Test SOM for single-threaded write"
27810         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27811                 error "write $tfile failed"
27812         check_lsom_size $DIR/$tfile $bs
27813
27814         local num=32
27815         local size=$(($num * $bs))
27816         local offset=0
27817         local i
27818
27819         echo "Test SOM for single client multi-threaded($num) write"
27820         $TRUNCATE $DIR/$tfile 0
27821         for ((i = 0; i < $num; i++)); do
27822                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27823                 local pids[$i]=$!
27824                 offset=$((offset + $bs))
27825         done
27826         for (( i=0; i < $num; i++ )); do
27827                 wait ${pids[$i]}
27828         done
27829         check_lsom_size $DIR/$tfile $size
27830
27831         $TRUNCATE $DIR/$tfile 0
27832         for ((i = 0; i < $num; i++)); do
27833                 offset=$((offset - $bs))
27834                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27835                 local pids[$i]=$!
27836         done
27837         for (( i=0; i < $num; i++ )); do
27838                 wait ${pids[$i]}
27839         done
27840         check_lsom_size $DIR/$tfile $size
27841
27842         # multi-client writes
27843         num=$(get_node_count ${CLIENTS//,/ })
27844         size=$(($num * $bs))
27845         offset=0
27846         i=0
27847
27848         echo "Test SOM for multi-client ($num) writes"
27849         $TRUNCATE $DIR/$tfile 0
27850         for client in ${CLIENTS//,/ }; do
27851                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27852                 local pids[$i]=$!
27853                 i=$((i + 1))
27854                 offset=$((offset + $bs))
27855         done
27856         for (( i=0; i < $num; i++ )); do
27857                 wait ${pids[$i]}
27858         done
27859         check_lsom_size $DIR/$tfile $offset
27860
27861         i=0
27862         $TRUNCATE $DIR/$tfile 0
27863         for client in ${CLIENTS//,/ }; do
27864                 offset=$((offset - $bs))
27865                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27866                 local pids[$i]=$!
27867                 i=$((i + 1))
27868         done
27869         for (( i=0; i < $num; i++ )); do
27870                 wait ${pids[$i]}
27871         done
27872         check_lsom_size $DIR/$tfile $size
27873
27874         # verify truncate
27875         echo "Test SOM for truncate"
27876         $TRUNCATE $DIR/$tfile 1048576
27877         check_lsom_size $DIR/$tfile 1048576
27878         $TRUNCATE $DIR/$tfile 1234
27879         check_lsom_size $DIR/$tfile 1234
27880
27881         # verify SOM blocks count
27882         echo "Verify SOM block count"
27883         $TRUNCATE $DIR/$tfile 0
27884         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27885                 error "failed to write file $tfile"
27886         check_lsom_data $DIR/$tfile
27887 }
27888 run_test 806 "Verify Lazy Size on MDS"
27889
27890 test_807() {
27891         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27892         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27893                 skip "Need MDS version at least 2.11.52"
27894
27895         # Registration step
27896         changelog_register || error "changelog_register failed"
27897         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27898         changelog_users $SINGLEMDS | grep -q $cl_user ||
27899                 error "User $cl_user not found in changelog_users"
27900
27901         rm -rf $DIR/$tdir || error "rm $tdir failed"
27902         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27903         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27904         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27905         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27906                 error "truncate $tdir/trunc failed"
27907
27908         local bs=1048576
27909         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27910                 error "write $tfile failed"
27911
27912         # multi-client wirtes
27913         local num=$(get_node_count ${CLIENTS//,/ })
27914         local offset=0
27915         local i=0
27916
27917         echo "Test SOM for multi-client ($num) writes"
27918         touch $DIR/$tfile || error "touch $tfile failed"
27919         $TRUNCATE $DIR/$tfile 0
27920         for client in ${CLIENTS//,/ }; do
27921                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27922                 local pids[$i]=$!
27923                 i=$((i + 1))
27924                 offset=$((offset + $bs))
27925         done
27926         for (( i=0; i < $num; i++ )); do
27927                 wait ${pids[$i]}
27928         done
27929
27930         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27931         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27932         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27933         check_lsom_data $DIR/$tdir/trunc
27934         check_lsom_data $DIR/$tdir/single_dd
27935         check_lsom_data $DIR/$tfile
27936
27937         rm -rf $DIR/$tdir
27938         # Deregistration step
27939         changelog_deregister || error "changelog_deregister failed"
27940 }
27941 run_test 807 "verify LSOM syncing tool"
27942
27943 check_som_nologged()
27944 {
27945         local lines=$($LFS changelog $FSNAME-MDT0000 |
27946                 grep 'x=trusted.som' | wc -l)
27947         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27948 }
27949
27950 test_808() {
27951         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27952                 skip "Need MDS version at least 2.11.55"
27953
27954         # Registration step
27955         changelog_register || error "changelog_register failed"
27956
27957         touch $DIR/$tfile || error "touch $tfile failed"
27958         check_som_nologged
27959
27960         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27961                 error "write $tfile failed"
27962         check_som_nologged
27963
27964         $TRUNCATE $DIR/$tfile 1234
27965         check_som_nologged
27966
27967         $TRUNCATE $DIR/$tfile 1048576
27968         check_som_nologged
27969
27970         # Deregistration step
27971         changelog_deregister || error "changelog_deregister failed"
27972 }
27973 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27974
27975 check_som_nodata()
27976 {
27977         $LFS getsom $1
27978         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27979 }
27980
27981 test_809() {
27982         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27983                 skip "Need MDS version at least 2.11.56"
27984
27985         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27986                 error "failed to create DoM-only file $DIR/$tfile"
27987         touch $DIR/$tfile || error "touch $tfile failed"
27988         check_som_nodata $DIR/$tfile
27989
27990         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27991                 error "write $tfile failed"
27992         check_som_nodata $DIR/$tfile
27993
27994         $TRUNCATE $DIR/$tfile 1234
27995         check_som_nodata $DIR/$tfile
27996
27997         $TRUNCATE $DIR/$tfile 4097
27998         check_som_nodata $DIR/$file
27999 }
28000 run_test 809 "Verify no SOM xattr store for DoM-only files"
28001
28002 test_810() {
28003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28004         $GSS && skip_env "could not run with gss"
28005         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28006                 skip "OST < 2.12.58 doesn't align checksum"
28007
28008         set_checksums 1
28009         stack_trap "set_checksums $ORIG_CSUM" EXIT
28010         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28011
28012         local csum
28013         local before
28014         local after
28015         for csum in $CKSUM_TYPES; do
28016                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28017                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28018                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28019                         eval set -- $i
28020                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28021                         before=$(md5sum $DIR/$tfile)
28022                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28023                         after=$(md5sum $DIR/$tfile)
28024                         [ "$before" == "$after" ] ||
28025                                 error "$csum: $before != $after bs=$1 seek=$2"
28026                 done
28027         done
28028 }
28029 run_test 810 "partial page writes on ZFS (LU-11663)"
28030
28031 test_812a() {
28032         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28033                 skip "OST < 2.12.51 doesn't support this fail_loc"
28034
28035         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28036         # ensure ost1 is connected
28037         stat $DIR/$tfile >/dev/null || error "can't stat"
28038         wait_osc_import_state client ost1 FULL
28039         # no locks, no reqs to let the connection idle
28040         cancel_lru_locks osc
28041
28042         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28043 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28044         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28045         wait_osc_import_state client ost1 CONNECTING
28046         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28047
28048         stat $DIR/$tfile >/dev/null || error "can't stat file"
28049 }
28050 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28051
28052 test_812b() { # LU-12378
28053         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28054                 skip "OST < 2.12.51 doesn't support this fail_loc"
28055
28056         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28057         # ensure ost1 is connected
28058         stat $DIR/$tfile >/dev/null || error "can't stat"
28059         wait_osc_import_state client ost1 FULL
28060         # no locks, no reqs to let the connection idle
28061         cancel_lru_locks osc
28062
28063         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28064 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28065         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28066         wait_osc_import_state client ost1 CONNECTING
28067         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28068
28069         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28070         wait_osc_import_state client ost1 IDLE
28071 }
28072 run_test 812b "do not drop no resend request for idle connect"
28073
28074 test_812c() {
28075         local old
28076
28077         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28078
28079         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28080         $LFS getstripe $DIR/$tfile
28081         $LCTL set_param osc.*.idle_timeout=10
28082         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28083         # ensure ost1 is connected
28084         stat $DIR/$tfile >/dev/null || error "can't stat"
28085         wait_osc_import_state client ost1 FULL
28086         # no locks, no reqs to let the connection idle
28087         cancel_lru_locks osc
28088
28089 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28090         $LCTL set_param fail_loc=0x80000533
28091         sleep 15
28092         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28093 }
28094 run_test 812c "idle import vs lock enqueue race"
28095
28096 test_813() {
28097         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28098         [ -z "$file_heat_sav" ] && skip "no file heat support"
28099
28100         local readsample
28101         local writesample
28102         local readbyte
28103         local writebyte
28104         local readsample1
28105         local writesample1
28106         local readbyte1
28107         local writebyte1
28108
28109         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28110         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28111
28112         $LCTL set_param -n llite.*.file_heat=1
28113         echo "Turn on file heat"
28114         echo "Period second: $period_second, Decay percentage: $decay_pct"
28115
28116         echo "QQQQ" > $DIR/$tfile
28117         echo "QQQQ" > $DIR/$tfile
28118         echo "QQQQ" > $DIR/$tfile
28119         cat $DIR/$tfile > /dev/null
28120         cat $DIR/$tfile > /dev/null
28121         cat $DIR/$tfile > /dev/null
28122         cat $DIR/$tfile > /dev/null
28123
28124         local out=$($LFS heat_get $DIR/$tfile)
28125
28126         $LFS heat_get $DIR/$tfile
28127         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28128         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28129         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28130         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28131
28132         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28133         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28134         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28135         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28136
28137         sleep $((period_second + 3))
28138         echo "Sleep $((period_second + 3)) seconds..."
28139         # The recursion formula to calculate the heat of the file f is as
28140         # follow:
28141         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28142         # Where Hi is the heat value in the period between time points i*I and
28143         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28144         # to the weight of Ci.
28145         out=$($LFS heat_get $DIR/$tfile)
28146         $LFS heat_get $DIR/$tfile
28147         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28148         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28149         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28150         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28151
28152         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28153                 error "read sample ($readsample) is wrong"
28154         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28155                 error "write sample ($writesample) is wrong"
28156         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28157                 error "read bytes ($readbyte) is wrong"
28158         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28159                 error "write bytes ($writebyte) is wrong"
28160
28161         echo "QQQQ" > $DIR/$tfile
28162         echo "QQQQ" > $DIR/$tfile
28163         echo "QQQQ" > $DIR/$tfile
28164         cat $DIR/$tfile > /dev/null
28165         cat $DIR/$tfile > /dev/null
28166         cat $DIR/$tfile > /dev/null
28167         cat $DIR/$tfile > /dev/null
28168
28169         sleep $((period_second + 3))
28170         echo "Sleep $((period_second + 3)) seconds..."
28171
28172         out=$($LFS heat_get $DIR/$tfile)
28173         $LFS heat_get $DIR/$tfile
28174         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28175         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28176         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28177         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28178
28179         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28180                 4 * $decay_pct) / 100") -eq 1 ] ||
28181                 error "read sample ($readsample1) is wrong"
28182         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28183                 3 * $decay_pct) / 100") -eq 1 ] ||
28184                 error "write sample ($writesample1) is wrong"
28185         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28186                 20 * $decay_pct) / 100") -eq 1 ] ||
28187                 error "read bytes ($readbyte1) is wrong"
28188         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28189                 15 * $decay_pct) / 100") -eq 1 ] ||
28190                 error "write bytes ($writebyte1) is wrong"
28191
28192         echo "Turn off file heat for the file $DIR/$tfile"
28193         $LFS heat_set -o $DIR/$tfile
28194
28195         echo "QQQQ" > $DIR/$tfile
28196         echo "QQQQ" > $DIR/$tfile
28197         echo "QQQQ" > $DIR/$tfile
28198         cat $DIR/$tfile > /dev/null
28199         cat $DIR/$tfile > /dev/null
28200         cat $DIR/$tfile > /dev/null
28201         cat $DIR/$tfile > /dev/null
28202
28203         out=$($LFS heat_get $DIR/$tfile)
28204         $LFS heat_get $DIR/$tfile
28205         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28206         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28207         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28208         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28209
28210         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28211         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28212         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28213         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28214
28215         echo "Trun on file heat for the file $DIR/$tfile"
28216         $LFS heat_set -O $DIR/$tfile
28217
28218         echo "QQQQ" > $DIR/$tfile
28219         echo "QQQQ" > $DIR/$tfile
28220         echo "QQQQ" > $DIR/$tfile
28221         cat $DIR/$tfile > /dev/null
28222         cat $DIR/$tfile > /dev/null
28223         cat $DIR/$tfile > /dev/null
28224         cat $DIR/$tfile > /dev/null
28225
28226         out=$($LFS heat_get $DIR/$tfile)
28227         $LFS heat_get $DIR/$tfile
28228         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28229         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28230         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28231         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28232
28233         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28234         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28235         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28236         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28237
28238         $LFS heat_set -c $DIR/$tfile
28239         $LCTL set_param -n llite.*.file_heat=0
28240         echo "Turn off file heat support for the Lustre filesystem"
28241
28242         echo "QQQQ" > $DIR/$tfile
28243         echo "QQQQ" > $DIR/$tfile
28244         echo "QQQQ" > $DIR/$tfile
28245         cat $DIR/$tfile > /dev/null
28246         cat $DIR/$tfile > /dev/null
28247         cat $DIR/$tfile > /dev/null
28248         cat $DIR/$tfile > /dev/null
28249
28250         out=$($LFS heat_get $DIR/$tfile)
28251         $LFS heat_get $DIR/$tfile
28252         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28253         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28254         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28255         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28256
28257         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28258         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28259         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28260         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28261
28262         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28263         rm -f $DIR/$tfile
28264 }
28265 run_test 813 "File heat verfication"
28266
28267 test_814()
28268 {
28269         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28270         echo -n y >> $DIR/$tfile
28271         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28272         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28273 }
28274 run_test 814 "sparse cp works as expected (LU-12361)"
28275
28276 test_815()
28277 {
28278         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28279         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28280 }
28281 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28282
28283 test_816() {
28284         local ost1_imp=$(get_osc_import_name client ost1)
28285         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28286                          cut -d'.' -f2)
28287
28288         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28289         # ensure ost1 is connected
28290
28291         stat $DIR/$tfile >/dev/null || error "can't stat"
28292         wait_osc_import_state client ost1 FULL
28293         # no locks, no reqs to let the connection idle
28294         cancel_lru_locks osc
28295         lru_resize_disable osc
28296         local before
28297         local now
28298         before=$($LCTL get_param -n \
28299                  ldlm.namespaces.$imp_name.lru_size)
28300
28301         wait_osc_import_state client ost1 IDLE
28302         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28303         now=$($LCTL get_param -n \
28304               ldlm.namespaces.$imp_name.lru_size)
28305         [ $before == $now ] || error "lru_size changed $before != $now"
28306 }
28307 run_test 816 "do not reset lru_resize on idle reconnect"
28308
28309 cleanup_817() {
28310         umount $tmpdir
28311         exportfs -u localhost:$DIR/nfsexp
28312         rm -rf $DIR/nfsexp
28313 }
28314
28315 test_817() {
28316         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28317
28318         mkdir -p $DIR/nfsexp
28319         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28320                 error "failed to export nfs"
28321
28322         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28323         stack_trap cleanup_817 EXIT
28324
28325         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28326                 error "failed to mount nfs to $tmpdir"
28327
28328         cp /bin/true $tmpdir
28329         $DIR/nfsexp/true || error "failed to execute 'true' command"
28330 }
28331 run_test 817 "nfsd won't cache write lock for exec file"
28332
28333 test_818() {
28334         test_mkdir -i0 -c1 $DIR/$tdir
28335         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28336         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28337         stop $SINGLEMDS
28338
28339         # restore osp-syn threads
28340         stack_trap "fail $SINGLEMDS"
28341
28342         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28343         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28344         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28345                 error "start $SINGLEMDS failed"
28346         rm -rf $DIR/$tdir
28347
28348         local testid=$(echo $TESTNAME | tr '_' ' ')
28349
28350         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28351                 grep "run LFSCK" || error "run LFSCK is not suggested"
28352 }
28353 run_test 818 "unlink with failed llog"
28354
28355 test_819a() {
28356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28357         cancel_lru_locks osc
28358         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28359         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28360         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28361         rm -f $TDIR/$tfile
28362 }
28363 run_test 819a "too big niobuf in read"
28364
28365 test_819b() {
28366         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28367         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28368         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28369         cancel_lru_locks osc
28370         sleep 1
28371         rm -f $TDIR/$tfile
28372 }
28373 run_test 819b "too big niobuf in write"
28374
28375
28376 function test_820_start_ost() {
28377         sleep 5
28378
28379         for num in $(seq $OSTCOUNT); do
28380                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28381         done
28382 }
28383
28384 test_820() {
28385         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28386
28387         mkdir $DIR/$tdir
28388         umount_client $MOUNT || error "umount failed"
28389         for num in $(seq $OSTCOUNT); do
28390                 stop ost$num
28391         done
28392
28393         # mount client with no active OSTs
28394         # so that the client can't initialize max LOV EA size
28395         # from OSC notifications
28396         mount_client $MOUNT || error "mount failed"
28397         # delay OST starting to keep this 0 max EA size for a while
28398         test_820_start_ost &
28399
28400         # create a directory on MDS2
28401         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28402                 error "Failed to create directory"
28403         # open intent should update default EA size
28404         # see mdc_update_max_ea_from_body()
28405         # notice this is the very first RPC to MDS2
28406         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28407         ret=$?
28408         echo $out
28409         # With SSK, this situation can lead to -EPERM being returned.
28410         # In that case, simply retry.
28411         if [ $ret -ne 0 ] && $SHARED_KEY; then
28412                 if echo "$out" | grep -q "not permitted"; then
28413                         cp /etc/services $DIR/$tdir/mds2
28414                         ret=$?
28415                 fi
28416         fi
28417         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28418 }
28419 run_test 820 "update max EA from open intent"
28420
28421 test_823() {
28422         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28423         local OST_MAX_PRECREATE=20000
28424
28425         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28426                 skip "Need MDS version at least 2.14.56"
28427
28428         save_lustre_params mds1 \
28429                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28430         do_facet $SINGLEMDS "$LCTL set_param -n \
28431                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28432         do_facet $SINGLEMDS "$LCTL set_param -n \
28433                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28434
28435         stack_trap "restore_lustre_params < $p; rm $p"
28436
28437         do_facet $SINGLEMDS "$LCTL set_param -n \
28438                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28439
28440         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28441                       osp.$FSNAME-OST0000*MDT0000.create_count")
28442         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28443                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28444         local expect_count=$(((($max/2)/256) * 256))
28445
28446         log "setting create_count to 100200:"
28447         log " -result- count: $count with max: $max, expecting: $expect_count"
28448
28449         [[ $count -eq expect_count ]] ||
28450                 error "Create count not set to max precreate."
28451 }
28452 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28453
28454 test_831() {
28455         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28456                 skip "Need MDS version 2.14.56"
28457
28458         local sync_changes=$(do_facet $SINGLEMDS \
28459                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28460
28461         [ "$sync_changes" -gt 100 ] &&
28462                 skip "Sync changes $sync_changes > 100 already"
28463
28464         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28465
28466         $LFS mkdir -i 0 $DIR/$tdir
28467         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28468
28469         save_lustre_params mds1 \
28470                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28471         save_lustre_params mds1 \
28472                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28473
28474         do_facet mds1 "$LCTL set_param -n \
28475                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28476                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28477         stack_trap "restore_lustre_params < $p" EXIT
28478
28479         createmany -o $DIR/$tdir/f- 1000
28480         unlinkmany $DIR/$tdir/f- 1000 &
28481         local UNLINK_PID=$!
28482
28483         while sleep 1; do
28484                 sync_changes=$(do_facet mds1 \
28485                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28486                 # the check in the code is racy, fail the test
28487                 # if the value above the limit by 10.
28488                 [ $sync_changes -gt 110 ] && {
28489                         kill -2 $UNLINK_PID
28490                         wait
28491                         error "osp changes throttling failed, $sync_changes>110"
28492                 }
28493                 kill -0 $UNLINK_PID 2> /dev/null || break
28494         done
28495         wait
28496 }
28497 run_test 831 "throttling unlink/setattr queuing on OSP"
28498
28499 #
28500 # tests that do cleanup/setup should be run at the end
28501 #
28502
28503 test_900() {
28504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28505         local ls
28506
28507         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28508         $LCTL set_param fail_loc=0x903
28509
28510         cancel_lru_locks MGC
28511
28512         FAIL_ON_ERROR=true cleanup
28513         FAIL_ON_ERROR=true setup
28514 }
28515 run_test 900 "umount should not race with any mgc requeue thread"
28516
28517 # LUS-6253/LU-11185
28518 test_901() {
28519         local old
28520         local count
28521         local oldc
28522         local newc
28523         local olds
28524         local news
28525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28526
28527         # some get_param have a bug to handle dot in param name
28528         cancel_lru_locks MGC
28529         old=$(mount -t lustre | wc -l)
28530         # 1 config+sptlrpc
28531         # 2 params
28532         # 3 nodemap
28533         # 4 IR
28534         old=$((old * 4))
28535         oldc=0
28536         count=0
28537         while [ $old -ne $oldc ]; do
28538                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28539                 sleep 1
28540                 ((count++))
28541                 if [ $count -ge $TIMEOUT ]; then
28542                         error "too large timeout"
28543                 fi
28544         done
28545         umount_client $MOUNT || error "umount failed"
28546         mount_client $MOUNT || error "mount failed"
28547         cancel_lru_locks MGC
28548         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28549
28550         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28551
28552         return 0
28553 }
28554 run_test 901 "don't leak a mgc lock on client umount"
28555
28556 # LU-13377
28557 test_902() {
28558         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28559                 skip "client does not have LU-13377 fix"
28560         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28561         $LCTL set_param fail_loc=0x1415
28562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28563         cancel_lru_locks osc
28564         rm -f $DIR/$tfile
28565 }
28566 run_test 902 "test short write doesn't hang lustre"
28567
28568 # LU-14711
28569 test_903() {
28570         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28571         echo "blah" > $DIR/${tfile}-2
28572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28573         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28574         $LCTL set_param fail_loc=0x417 fail_val=20
28575
28576         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28577         sleep 1 # To start the destroy
28578         wait_destroy_complete 150 || error "Destroy taking too long"
28579         cat $DIR/$tfile > /dev/null || error "Evicted"
28580 }
28581 run_test 903 "Test long page discard does not cause evictions"
28582
28583 test_904() {
28584         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28585         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28586                 grep -q project || skip "skip project quota not supported"
28587
28588         local testfile="$DIR/$tdir/$tfile"
28589         local xattr="trusted.projid"
28590         local projid
28591         local mdts=$(comma_list $(mdts_nodes))
28592         local saved=$(do_facet mds1 $LCTL get_param -n \
28593                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28594
28595         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28596         stack_trap "do_nodes $mdts $LCTL set_param \
28597                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28598
28599         mkdir -p $DIR/$tdir
28600         touch $testfile
28601         #hide projid xattr on server
28602         $LFS project -p 1 $testfile ||
28603                 error "set $testfile project id failed"
28604         getfattr -m - $testfile | grep $xattr &&
28605                 error "do not show trusted.projid when disabled on server"
28606         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28607         #should be hidden when projid is 0
28608         $LFS project -p 0 $testfile ||
28609                 error "set $testfile project id failed"
28610         getfattr -m - $testfile | grep $xattr &&
28611                 error "do not show trusted.projid with project ID 0"
28612
28613         #still can getxattr explicitly
28614         projid=$(getfattr -n $xattr $testfile |
28615                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28616         [ $projid == "0" ] ||
28617                 error "projid expected 0 not $projid"
28618
28619         #set the projid via setxattr
28620         setfattr -n $xattr -v "1000" $testfile ||
28621                 error "setattr failed with $?"
28622         projid=($($LFS project $testfile))
28623         [ ${projid[0]} == "1000" ] ||
28624                 error "projid expected 1000 not $projid"
28625
28626         #check the new projid via getxattr
28627         $LFS project -p 1001 $testfile ||
28628                 error "set $testfile project id failed"
28629         getfattr -m - $testfile | grep $xattr ||
28630                 error "should show trusted.projid when project ID != 0"
28631         projid=$(getfattr -n $xattr $testfile |
28632                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28633         [ $projid == "1001" ] ||
28634                 error "projid expected 1001 not $projid"
28635
28636         #try to set invalid projid
28637         setfattr -n $xattr -v "4294967295" $testfile &&
28638                 error "set invalid projid should fail"
28639
28640         #remove the xattr means setting projid to 0
28641         setfattr -x $xattr $testfile ||
28642                 error "setfattr failed with $?"
28643         projid=($($LFS project $testfile))
28644         [ ${projid[0]} == "0" ] ||
28645                 error "projid expected 0 not $projid"
28646
28647         #should be hidden when parent has inherit flag and same projid
28648         $LFS project -srp 1002 $DIR/$tdir ||
28649                 error "set $tdir project id failed"
28650         getfattr -m - $testfile | grep $xattr &&
28651                 error "do not show trusted.projid with inherit flag"
28652
28653         #still can getxattr explicitly
28654         projid=$(getfattr -n $xattr $testfile |
28655                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28656         [ $projid == "1002" ] ||
28657                 error "projid expected 1002 not $projid"
28658 }
28659 run_test 904 "virtual project ID xattr"
28660
28661 # LU-8582
28662 test_905() {
28663         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28664                 skip "lustre < 2.8.54 does not support ladvise"
28665
28666         remote_ost_nodsh && skip "remote OST with nodsh"
28667         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28668
28669         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28670
28671         #define OBD_FAIL_OST_OPCODE 0x253
28672         # OST_LADVISE = 21
28673         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28674         $LFS ladvise -a willread $DIR/$tfile &&
28675                 error "unexpected success of ladvise with fault injection"
28676         $LFS ladvise -a willread $DIR/$tfile |&
28677                 grep -q "Operation not supported"
28678         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28679 }
28680 run_test 905 "bad or new opcode should not stuck client"
28681
28682 complete $SECONDS
28683 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28684 check_and_cleanup_lustre
28685 if [ "$I_MOUNTED" != "yes" ]; then
28686         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28687 fi
28688 exit_status