Whamcloud - gitweb
c7a0cfa154f7d64e0c380f4cdf5466c4cfb01e38
[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         trunc_test 42d 0
5362         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5363                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5364         rm $file
5365 }
5366 run_test 42d "test complete truncate of file with cached dirty data"
5367
5368 test_42e() { # bug22074
5369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5370
5371         local TDIR=$DIR/${tdir}e
5372         local pages=16 # hardcoded 16 pages, don't change it.
5373         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5374         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5375         local max_dirty_mb
5376         local warmup_files
5377
5378         test_mkdir $DIR/${tdir}e
5379         $LFS setstripe -c 1 $TDIR
5380         createmany -o $TDIR/f $files
5381
5382         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5383
5384         # we assume that with $OSTCOUNT files, at least one of them will
5385         # be allocated on OST0.
5386         warmup_files=$((OSTCOUNT * max_dirty_mb))
5387         createmany -o $TDIR/w $warmup_files
5388
5389         # write a large amount of data into one file and sync, to get good
5390         # avail_grant number from OST.
5391         for ((i=0; i<$warmup_files; i++)); do
5392                 idx=$($LFS getstripe -i $TDIR/w$i)
5393                 [ $idx -ne 0 ] && continue
5394                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5395                 break
5396         done
5397         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5398         sync
5399         $LCTL get_param $proc_osc0/cur_dirty_bytes
5400         $LCTL get_param $proc_osc0/cur_grant_bytes
5401
5402         # create as much dirty pages as we can while not to trigger the actual
5403         # RPCs directly. but depends on the env, VFS may trigger flush during this
5404         # period, hopefully we are good.
5405         for ((i=0; i<$warmup_files; i++)); do
5406                 idx=$($LFS getstripe -i $TDIR/w$i)
5407                 [ $idx -ne 0 ] && continue
5408                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5409         done
5410         $LCTL get_param $proc_osc0/cur_dirty_bytes
5411         $LCTL get_param $proc_osc0/cur_grant_bytes
5412
5413         # perform the real test
5414         $LCTL set_param $proc_osc0/rpc_stats 0
5415         for ((;i<$files; i++)); do
5416                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5417                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5418         done
5419         sync
5420         $LCTL get_param $proc_osc0/rpc_stats
5421
5422         local percent=0
5423         local have_ppr=false
5424         $LCTL get_param $proc_osc0/rpc_stats |
5425                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5426                         # skip lines until we are at the RPC histogram data
5427                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5428                         $have_ppr || continue
5429
5430                         # we only want the percent stat for < 16 pages
5431                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5432
5433                         percent=$((percent + WPCT))
5434                         if [[ $percent -gt 15 ]]; then
5435                                 error "less than 16-pages write RPCs" \
5436                                       "$percent% > 15%"
5437                                 break
5438                         fi
5439                 done
5440         rm -rf $TDIR
5441 }
5442 run_test 42e "verify sub-RPC writes are not done synchronously"
5443
5444 test_43A() { # was test_43
5445         test_mkdir $DIR/$tdir
5446         cp -p /bin/ls $DIR/$tdir/$tfile
5447         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5448         pid=$!
5449         # give multiop a chance to open
5450         sleep 1
5451
5452         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5453         kill -USR1 $pid
5454         # Wait for multiop to exit
5455         wait $pid
5456 }
5457 run_test 43A "execution of file opened for write should return -ETXTBSY"
5458
5459 test_43a() {
5460         test_mkdir $DIR/$tdir
5461         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5462         $DIR/$tdir/sleep 60 &
5463         SLEEP_PID=$!
5464         # Make sure exec of $tdir/sleep wins race with truncate
5465         sleep 1
5466         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5467         kill $SLEEP_PID
5468 }
5469 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5470
5471 test_43b() {
5472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5473
5474         test_mkdir $DIR/$tdir
5475         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5476         $DIR/$tdir/sleep 60 &
5477         SLEEP_PID=$!
5478         # Make sure exec of $tdir/sleep wins race with truncate
5479         sleep 1
5480         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5481         kill $SLEEP_PID
5482 }
5483 run_test 43b "truncate of file being executed should return -ETXTBSY"
5484
5485 test_43c() {
5486         local testdir="$DIR/$tdir"
5487         test_mkdir $testdir
5488         cp $SHELL $testdir/
5489         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5490                 ( cd $testdir && md5sum -c )
5491 }
5492 run_test 43c "md5sum of copy into lustre"
5493
5494 test_44A() { # was test_44
5495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5496
5497         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5498         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5499 }
5500 run_test 44A "zero length read from a sparse stripe"
5501
5502 test_44a() {
5503         local nstripe=$($LFS getstripe -c -d $DIR)
5504         [ -z "$nstripe" ] && skip "can't get stripe info"
5505         [[ $nstripe -gt $OSTCOUNT ]] &&
5506                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5507
5508         local stride=$($LFS getstripe -S -d $DIR)
5509         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5510                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5511         fi
5512
5513         OFFSETS="0 $((stride/2)) $((stride-1))"
5514         for offset in $OFFSETS; do
5515                 for i in $(seq 0 $((nstripe-1))); do
5516                         local GLOBALOFFSETS=""
5517                         # size in Bytes
5518                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5519                         local myfn=$DIR/d44a-$size
5520                         echo "--------writing $myfn at $size"
5521                         ll_sparseness_write $myfn $size ||
5522                                 error "ll_sparseness_write"
5523                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5524                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5525                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5526
5527                         for j in $(seq 0 $((nstripe-1))); do
5528                                 # size in Bytes
5529                                 size=$((((j + $nstripe )*$stride + $offset)))
5530                                 ll_sparseness_write $myfn $size ||
5531                                         error "ll_sparseness_write"
5532                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5533                         done
5534                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5535                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5536                         rm -f $myfn
5537                 done
5538         done
5539 }
5540 run_test 44a "test sparse pwrite ==============================="
5541
5542 dirty_osc_total() {
5543         tot=0
5544         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5545                 tot=$(($tot + $d))
5546         done
5547         echo $tot
5548 }
5549 do_dirty_record() {
5550         before=`dirty_osc_total`
5551         echo executing "\"$*\""
5552         eval $*
5553         after=`dirty_osc_total`
5554         echo before $before, after $after
5555 }
5556 test_45() {
5557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5558
5559         f="$DIR/f45"
5560         # Obtain grants from OST if it supports it
5561         echo blah > ${f}_grant
5562         stop_writeback
5563         sync
5564         do_dirty_record "echo blah > $f"
5565         [[ $before -eq $after ]] && error "write wasn't cached"
5566         do_dirty_record "> $f"
5567         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5568         do_dirty_record "echo blah > $f"
5569         [[ $before -eq $after ]] && error "write wasn't cached"
5570         do_dirty_record "sync"
5571         [[ $before -gt $after ]] || error "writeback 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 "cancel_lru_locks osc"
5575         [[ $before -gt $after ]] ||
5576                 error "lock cancellation didn't lower dirty count"
5577         start_writeback
5578 }
5579 run_test 45 "osc io page accounting ============================"
5580
5581 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5582 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5583 # objects offset and an assert hit when an rpc was built with 1023's mapped
5584 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5585 test_46() {
5586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5587
5588         f="$DIR/f46"
5589         stop_writeback
5590         sync
5591         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5592         sync
5593         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5594         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         start_writeback
5597 }
5598 run_test 46 "dirtying a previously written page ================"
5599
5600 # test_47 is removed "Device nodes check" is moved to test_28
5601
5602 test_48a() { # bug 2399
5603         [ "$mds1_FSTYPE" = "zfs" ] &&
5604         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5605                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5606
5607         test_mkdir $DIR/$tdir
5608         cd $DIR/$tdir
5609         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5610         test_mkdir $DIR/$tdir
5611         touch foo || error "'touch foo' failed after recreating cwd"
5612         test_mkdir bar
5613         touch .foo || error "'touch .foo' failed after recreating cwd"
5614         test_mkdir .bar
5615         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5616         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5617         cd . || error "'cd .' failed after recreating cwd"
5618         mkdir . && error "'mkdir .' worked after recreating cwd"
5619         rmdir . && error "'rmdir .' worked after recreating cwd"
5620         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5621         cd .. || error "'cd ..' failed after recreating cwd"
5622 }
5623 run_test 48a "Access renamed working dir (should return errors)="
5624
5625 test_48b() { # bug 2399
5626         rm -rf $DIR/$tdir
5627         test_mkdir $DIR/$tdir
5628         cd $DIR/$tdir
5629         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5630         touch foo && error "'touch foo' worked after removing cwd"
5631         mkdir foo && error "'mkdir foo' worked after removing cwd"
5632         touch .foo && error "'touch .foo' worked after removing cwd"
5633         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5634         ls . > /dev/null && error "'ls .' worked after removing cwd"
5635         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5636         mkdir . && error "'mkdir .' worked after removing cwd"
5637         rmdir . && error "'rmdir .' worked after removing cwd"
5638         ln -s . foo && error "'ln -s .' worked after removing cwd"
5639         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5640 }
5641 run_test 48b "Access removed working dir (should return errors)="
5642
5643 test_48c() { # bug 2350
5644         #lctl set_param debug=-1
5645         #set -vx
5646         rm -rf $DIR/$tdir
5647         test_mkdir -p $DIR/$tdir/dir
5648         cd $DIR/$tdir/dir
5649         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5650         $TRACE touch foo && error "touch foo worked after removing cwd"
5651         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5652         touch .foo && error "touch .foo worked after removing cwd"
5653         mkdir .foo && error "mkdir .foo worked after removing cwd"
5654         $TRACE ls . && error "'ls .' worked after removing cwd"
5655         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5656         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5657         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5658         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5659         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5660 }
5661 run_test 48c "Access removed working subdir (should return errors)"
5662
5663 test_48d() { # bug 2350
5664         #lctl set_param debug=-1
5665         #set -vx
5666         rm -rf $DIR/$tdir
5667         test_mkdir -p $DIR/$tdir/dir
5668         cd $DIR/$tdir/dir
5669         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5670         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5671         $TRACE touch foo && error "'touch foo' worked after removing parent"
5672         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5673         touch .foo && error "'touch .foo' worked after removing parent"
5674         mkdir .foo && error "mkdir .foo worked after removing parent"
5675         $TRACE ls . && error "'ls .' worked after removing parent"
5676         $TRACE ls .. && error "'ls ..' worked after removing parent"
5677         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5678         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5679         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5680         true
5681 }
5682 run_test 48d "Access removed parent subdir (should return errors)"
5683
5684 test_48e() { # bug 4134
5685         #lctl set_param debug=-1
5686         #set -vx
5687         rm -rf $DIR/$tdir
5688         test_mkdir -p $DIR/$tdir/dir
5689         cd $DIR/$tdir/dir
5690         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5691         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5692         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5693         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5694         # On a buggy kernel addition of "touch foo" after cd .. will
5695         # produce kernel oops in lookup_hash_it
5696         touch ../foo && error "'cd ..' worked after recreate parent"
5697         cd $DIR
5698         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5699 }
5700 run_test 48e "Access to recreated parent subdir (should return errors)"
5701
5702 test_48f() {
5703         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5704                 skip "need MDS >= 2.13.55"
5705         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5706         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5707                 skip "needs different host for mdt1 mdt2"
5708         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5709
5710         $LFS mkdir -i0 $DIR/$tdir
5711         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5712
5713         for d in sub1 sub2 sub3; do
5714                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5715                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5716                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5717         done
5718
5719         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5720 }
5721 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5722
5723 test_49() { # LU-1030
5724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5725         remote_ost_nodsh && skip "remote OST with nodsh"
5726
5727         # get ost1 size - $FSNAME-OST0000
5728         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5729                 awk '{ print $4 }')
5730         # write 800M at maximum
5731         [[ $ost1_size -lt 2 ]] && ost1_size=2
5732         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5733
5734         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5735         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5736         local dd_pid=$!
5737
5738         # change max_pages_per_rpc while writing the file
5739         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5740         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5741         # loop until dd process exits
5742         while ps ax -opid | grep -wq $dd_pid; do
5743                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5744                 sleep $((RANDOM % 5 + 1))
5745         done
5746         # restore original max_pages_per_rpc
5747         $LCTL set_param $osc1_mppc=$orig_mppc
5748         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5749 }
5750 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5751
5752 test_50() {
5753         # bug 1485
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5757 }
5758 run_test 50 "special situations: /proc symlinks  ==============="
5759
5760 test_51a() {    # was test_51
5761         # bug 1516 - create an empty entry right after ".." then split dir
5762         test_mkdir -c1 $DIR/$tdir
5763         touch $DIR/$tdir/foo
5764         $MCREATE $DIR/$tdir/bar
5765         rm $DIR/$tdir/foo
5766         createmany -m $DIR/$tdir/longfile 201
5767         FNUM=202
5768         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5769                 $MCREATE $DIR/$tdir/longfile$FNUM
5770                 FNUM=$(($FNUM + 1))
5771                 echo -n "+"
5772         done
5773         echo
5774         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5775 }
5776 run_test 51a "special situations: split htree with empty entry =="
5777
5778 cleanup_print_lfs_df () {
5779         trap 0
5780         $LFS df
5781         $LFS df -i
5782 }
5783
5784 test_51b() {
5785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5786
5787         local dir=$DIR/$tdir
5788         local nrdirs=$((65536 + 100))
5789
5790         # cleanup the directory
5791         rm -fr $dir
5792
5793         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5794
5795         $LFS df
5796         $LFS df -i
5797         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5798         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5799         [[ $numfree -lt $nrdirs ]] &&
5800                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5801
5802         # need to check free space for the directories as well
5803         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5804         numfree=$(( blkfree / $(fs_inode_ksize) ))
5805         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5806
5807         trap cleanup_print_lfs_df EXIT
5808
5809         # create files
5810         createmany -d $dir/d $nrdirs || {
5811                 unlinkmany $dir/d $nrdirs
5812                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5813         }
5814
5815         # really created :
5816         nrdirs=$(ls -U $dir | wc -l)
5817
5818         # unlink all but 100 subdirectories, then check it still works
5819         local left=100
5820         local delete=$((nrdirs - left))
5821
5822         $LFS df
5823         $LFS df -i
5824
5825         # for ldiskfs the nlink count should be 1, but this is OSD specific
5826         # and so this is listed for informational purposes only
5827         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5828         unlinkmany -d $dir/d $delete ||
5829                 error "unlink of first $delete subdirs failed"
5830
5831         echo "nlink between: $(stat -c %h $dir)"
5832         local found=$(ls -U $dir | wc -l)
5833         [ $found -ne $left ] &&
5834                 error "can't find subdirs: found only $found, expected $left"
5835
5836         unlinkmany -d $dir/d $delete $left ||
5837                 error "unlink of second $left subdirs failed"
5838         # regardless of whether the backing filesystem tracks nlink accurately
5839         # or not, the nlink count shouldn't be more than "." and ".." here
5840         local after=$(stat -c %h $dir)
5841         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5842                 echo "nlink after: $after"
5843
5844         cleanup_print_lfs_df
5845 }
5846 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5847
5848 test_51d_sub() {
5849         local stripecount=$1
5850         local nfiles=$((200 * $OSTCOUNT))
5851
5852         log "create files with stripecount=$stripecount"
5853         $LFS setstripe -C $stripecount $DIR/$tdir
5854         createmany -o $DIR/$tdir/t- $nfiles
5855         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5856         for ((n = 0; n < $OSTCOUNT; n++)); do
5857                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5858                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5859                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5860                             '($1 == '$n') { objs += 1 } \
5861                             END { printf("%0.0f", objs) }')
5862                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5863         done
5864         unlinkmany $DIR/$tdir/t- $nfiles
5865         rm  -f $TMP/$tfile
5866
5867         local nlast
5868         local min=4
5869         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5870
5871         # For some combinations of stripecount and OSTCOUNT current code
5872         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5873         # than others. Rather than skipping this test entirely, check that
5874         # and keep testing to ensure imbalance does not get worse. LU-15282
5875         (( (OSTCOUNT == 6 && stripecount == 4) ||
5876            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5877            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5878         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5879                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5880                         { $LFS df && $LFS df -i &&
5881                         error "OST $n has fewer objects vs. OST $nlast " \
5882                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5883                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5884                         { $LFS df && $LFS df -i &&
5885                         error "OST $n has fewer objects vs. OST $nlast " \
5886                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5887
5888                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5889                         { $LFS df && $LFS df -i &&
5890                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5891                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5892                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5893                         { $LFS df && $LFS df -i &&
5894                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5895                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5896         done
5897 }
5898
5899 test_51d() {
5900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5901         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5902
5903         local stripecount
5904         local qos_old=$(do_facet mds1 \
5905                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5906
5907         do_nodes $(comma_list $(mdts_nodes)) \
5908                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5909         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5910                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5911
5912         test_mkdir $DIR/$tdir
5913
5914         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5915                 test_51d_sub $stripecount
5916         done
5917 }
5918 run_test 51d "check object distribution"
5919
5920 test_51e() {
5921         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5922                 skip_env "ldiskfs only test"
5923         fi
5924
5925         test_mkdir -c1 $DIR/$tdir
5926         test_mkdir -c1 $DIR/$tdir/d0
5927
5928         touch $DIR/$tdir/d0/foo
5929         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5930                 error "file exceed 65000 nlink limit!"
5931         unlinkmany $DIR/$tdir/d0/f- 65001
5932         return 0
5933 }
5934 run_test 51e "check file nlink limit"
5935
5936 test_51f() {
5937         test_mkdir $DIR/$tdir
5938
5939         local max=100000
5940         local ulimit_old=$(ulimit -n)
5941         local spare=20 # number of spare fd's for scripts/libraries, etc.
5942         local mdt=$($LFS getstripe -m $DIR/$tdir)
5943         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5944
5945         echo "MDT$mdt numfree=$numfree, max=$max"
5946         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5947         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5948                 while ! ulimit -n $((numfree + spare)); do
5949                         numfree=$((numfree * 3 / 4))
5950                 done
5951                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5952         else
5953                 echo "left ulimit at $ulimit_old"
5954         fi
5955
5956         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5957                 unlinkmany $DIR/$tdir/f $numfree
5958                 error "create+open $numfree files in $DIR/$tdir failed"
5959         }
5960         ulimit -n $ulimit_old
5961
5962         # if createmany exits at 120s there will be fewer than $numfree files
5963         unlinkmany $DIR/$tdir/f $numfree || true
5964 }
5965 run_test 51f "check many open files limit"
5966
5967 test_52a() {
5968         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5969         test_mkdir $DIR/$tdir
5970         touch $DIR/$tdir/foo
5971         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5972         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5973         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5974         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5975         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5976                                         error "link worked"
5977         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5978         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5979         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5980                                                      error "lsattr"
5981         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5982         cp -r $DIR/$tdir $TMP/
5983         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5984 }
5985 run_test 52a "append-only flag test (should return errors)"
5986
5987 test_52b() {
5988         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5989         test_mkdir $DIR/$tdir
5990         touch $DIR/$tdir/foo
5991         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5992         cat test > $DIR/$tdir/foo && error "cat test worked"
5993         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5994         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5995         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5996                                         error "link worked"
5997         echo foo >> $DIR/$tdir/foo && error "echo worked"
5998         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5999         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6000         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6001         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6002                                                         error "lsattr"
6003         chattr -i $DIR/$tdir/foo || error "chattr failed"
6004
6005         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6006 }
6007 run_test 52b "immutable flag test (should return errors) ======="
6008
6009 test_53() {
6010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6011         remote_mds_nodsh && skip "remote MDS with nodsh"
6012         remote_ost_nodsh && skip "remote OST with nodsh"
6013
6014         local param
6015         local param_seq
6016         local ostname
6017         local mds_last
6018         local mds_last_seq
6019         local ost_last
6020         local ost_last_seq
6021         local ost_last_id
6022         local ostnum
6023         local node
6024         local found=false
6025         local support_last_seq=true
6026
6027         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6028                 support_last_seq=false
6029
6030         # only test MDT0000
6031         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6032         local value
6033         for value in $(do_facet $SINGLEMDS \
6034                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6035                 param=$(echo ${value[0]} | cut -d "=" -f1)
6036                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6037
6038                 if $support_last_seq; then
6039                         param_seq=$(echo $param |
6040                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6041                         mds_last_seq=$(do_facet $SINGLEMDS \
6042                                        $LCTL get_param -n $param_seq)
6043                 fi
6044                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6045
6046                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6047                 node=$(facet_active_host ost$((ostnum+1)))
6048                 param="obdfilter.$ostname.last_id"
6049                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6050                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6051                         ost_last_id=$ost_last
6052
6053                         if $support_last_seq; then
6054                                 ost_last_id=$(echo $ost_last |
6055                                               awk -F':' '{print $2}' |
6056                                               sed -e "s/^0x//g")
6057                                 ost_last_seq=$(echo $ost_last |
6058                                                awk -F':' '{print $1}')
6059                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6060                         fi
6061
6062                         if [[ $ost_last_id != $mds_last ]]; then
6063                                 error "$ost_last_id != $mds_last"
6064                         else
6065                                 found=true
6066                                 break
6067                         fi
6068                 done
6069         done
6070         $found || error "can not match last_seq/last_id for $mdtosc"
6071         return 0
6072 }
6073 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6074
6075 test_54a() {
6076         perl -MSocket -e ';' || skip "no Socket perl module installed"
6077
6078         $SOCKETSERVER $DIR/socket ||
6079                 error "$SOCKETSERVER $DIR/socket failed: $?"
6080         $SOCKETCLIENT $DIR/socket ||
6081                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6082         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6083 }
6084 run_test 54a "unix domain socket test =========================="
6085
6086 test_54b() {
6087         f="$DIR/f54b"
6088         mknod $f c 1 3
6089         chmod 0666 $f
6090         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6091 }
6092 run_test 54b "char device works in lustre ======================"
6093
6094 find_loop_dev() {
6095         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6096         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6097         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6098
6099         for i in $(seq 3 7); do
6100                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6101                 LOOPDEV=$LOOPBASE$i
6102                 LOOPNUM=$i
6103                 break
6104         done
6105 }
6106
6107 cleanup_54c() {
6108         local rc=0
6109         loopdev="$DIR/loop54c"
6110
6111         trap 0
6112         $UMOUNT $DIR/$tdir || rc=$?
6113         losetup -d $loopdev || true
6114         losetup -d $LOOPDEV || true
6115         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6116         return $rc
6117 }
6118
6119 test_54c() {
6120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6121
6122         loopdev="$DIR/loop54c"
6123
6124         find_loop_dev
6125         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6126         trap cleanup_54c EXIT
6127         mknod $loopdev b 7 $LOOPNUM
6128         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6129         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6130         losetup $loopdev $DIR/$tfile ||
6131                 error "can't set up $loopdev for $DIR/$tfile"
6132         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6133         test_mkdir $DIR/$tdir
6134         mount -t ext2 $loopdev $DIR/$tdir ||
6135                 error "error mounting $loopdev on $DIR/$tdir"
6136         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6137                 error "dd write"
6138         df $DIR/$tdir
6139         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6140                 error "dd read"
6141         cleanup_54c
6142 }
6143 run_test 54c "block device works in lustre ====================="
6144
6145 test_54d() {
6146         local pipe="$DIR/$tfile.pipe"
6147         local string="aaaaaa"
6148
6149         mknod $pipe p
6150         echo -n "$string" > $pipe &
6151         local result=$(cat $pipe)
6152         [[ "$result" == "$string" ]] || error "$result != $string"
6153 }
6154 run_test 54d "fifo device works in lustre ======================"
6155
6156 test_54e() {
6157         f="$DIR/f54e"
6158         string="aaaaaa"
6159         cp -aL /dev/console $f
6160         echo $string > $f || error "echo $string to $f failed"
6161 }
6162 run_test 54e "console/tty device works in lustre ======================"
6163
6164 test_56a() {
6165         local numfiles=3
6166         local numdirs=2
6167         local dir=$DIR/$tdir
6168
6169         rm -rf $dir
6170         test_mkdir -p $dir/dir
6171         for i in $(seq $numfiles); do
6172                 touch $dir/file$i
6173                 touch $dir/dir/file$i
6174         done
6175
6176         local numcomp=$($LFS getstripe --component-count $dir)
6177
6178         [[ $numcomp == 0 ]] && numcomp=1
6179
6180         # test lfs getstripe with --recursive
6181         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6182
6183         [[ $filenum -eq $((numfiles * 2)) ]] ||
6184                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6185         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6186         [[ $filenum -eq $numfiles ]] ||
6187                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6188         echo "$LFS getstripe showed obdidx or l_ost_idx"
6189
6190         # test lfs getstripe with file instead of dir
6191         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6192         [[ $filenum -eq 1 ]] ||
6193                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6194         echo "$LFS getstripe file1 passed"
6195
6196         #test lfs getstripe with --verbose
6197         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6198         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6199                 error "$LFS getstripe --verbose $dir: "\
6200                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6201         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6202                 error "$LFS getstripe $dir: showed lmm_magic"
6203
6204         #test lfs getstripe with -v prints lmm_fid
6205         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6206         local countfids=$((numdirs + numfiles * numcomp))
6207         [[ $filenum -eq $countfids ]] ||
6208                 error "$LFS getstripe -v $dir: "\
6209                       "got $filenum want $countfids lmm_fid"
6210         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6211                 error "$LFS getstripe $dir: showed lmm_fid by default"
6212         echo "$LFS getstripe --verbose passed"
6213
6214         #check for FID information
6215         local fid1=$($LFS getstripe --fid $dir/file1)
6216         local fid2=$($LFS getstripe --verbose $dir/file1 |
6217                      awk '/lmm_fid: / { print $2; exit; }')
6218         local fid3=$($LFS path2fid $dir/file1)
6219
6220         [ "$fid1" != "$fid2" ] &&
6221                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6222         [ "$fid1" != "$fid3" ] &&
6223                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6224         echo "$LFS getstripe --fid passed"
6225
6226         #test lfs getstripe with --obd
6227         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6228                 error "$LFS getstripe --obd wrong_uuid: should return error"
6229
6230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6231
6232         local ostidx=1
6233         local obduuid=$(ostuuid_from_index $ostidx)
6234         local found=$($LFS getstripe -r --obd $obduuid $dir |
6235                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6236
6237         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6238         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6239                 ((filenum--))
6240         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6241                 ((filenum--))
6242
6243         [[ $found -eq $filenum ]] ||
6244                 error "$LFS getstripe --obd: found $found expect $filenum"
6245         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6246                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6247                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6248                 error "$LFS getstripe --obd: should not show file on other obd"
6249         echo "$LFS getstripe --obd passed"
6250 }
6251 run_test 56a "check $LFS getstripe"
6252
6253 test_56b() {
6254         local dir=$DIR/$tdir
6255         local numdirs=3
6256
6257         test_mkdir $dir
6258         for i in $(seq $numdirs); do
6259                 test_mkdir $dir/dir$i
6260         done
6261
6262         # test lfs getdirstripe default mode is non-recursion, which is
6263         # different from lfs getstripe
6264         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6265
6266         [[ $dircnt -eq 1 ]] ||
6267                 error "$LFS getdirstripe: found $dircnt, not 1"
6268         dircnt=$($LFS getdirstripe --recursive $dir |
6269                 grep -c lmv_stripe_count)
6270         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6271                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6272 }
6273 run_test 56b "check $LFS getdirstripe"
6274
6275 test_56c() {
6276         remote_ost_nodsh && skip "remote OST with nodsh"
6277
6278         local ost_idx=0
6279         local ost_name=$(ostname_from_index $ost_idx)
6280         local old_status=$(ost_dev_status $ost_idx)
6281         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6282
6283         [[ -z "$old_status" ]] ||
6284                 skip_env "OST $ost_name is in $old_status status"
6285
6286         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6287         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6288                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6289         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6290                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6291                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6292         fi
6293
6294         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6295                 error "$LFS df -v showing inactive devices"
6296         sleep_maxage
6297
6298         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6299
6300         [[ "$new_status" =~ "D" ]] ||
6301                 error "$ost_name status is '$new_status', missing 'D'"
6302         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6303                 [[ "$new_status" =~ "N" ]] ||
6304                         error "$ost_name status is '$new_status', missing 'N'"
6305         fi
6306         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6307                 [[ "$new_status" =~ "f" ]] ||
6308                         error "$ost_name status is '$new_status', missing 'f'"
6309         fi
6310
6311         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6312         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6313                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6314         [[ -z "$p" ]] && restore_lustre_params < $p || true
6315         sleep_maxage
6316
6317         new_status=$(ost_dev_status $ost_idx)
6318         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6319                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6320         # can't check 'f' as devices may actually be on flash
6321 }
6322 run_test 56c "check 'lfs df' showing device status"
6323
6324 test_56d() {
6325         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6326         local osts=$($LFS df -v $MOUNT | grep -c OST)
6327
6328         $LFS df $MOUNT
6329
6330         (( mdts == MDSCOUNT )) ||
6331                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6332         (( osts == OSTCOUNT )) ||
6333                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6334 }
6335 run_test 56d "'lfs df -v' prints only configured devices"
6336
6337 test_56e() {
6338         err_enoent=2 # No such file or directory
6339         err_eopnotsupp=95 # Operation not supported
6340
6341         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6342         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6343
6344         # Check for handling of path not exists
6345         output=$($LFS df $enoent_mnt 2>&1)
6346         ret=$?
6347
6348         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6349         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6350                 error "expect failure $err_enoent, not $ret"
6351
6352         # Check for handling of non-Lustre FS
6353         output=$($LFS df $notsup_mnt)
6354         ret=$?
6355
6356         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6357         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6358                 error "expect success $err_eopnotsupp, not $ret"
6359
6360         # Check for multiple LustreFS argument
6361         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6362         ret=$?
6363
6364         [[ $output -eq 3 && $ret -eq 0 ]] ||
6365                 error "expect success 3, not $output, rc = $ret"
6366
6367         # Check for correct non-Lustre FS handling among multiple
6368         # LustreFS argument
6369         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6370                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6371         ret=$?
6372
6373         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6374                 error "expect success 2, not $output, rc = $ret"
6375 }
6376 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6377
6378 NUMFILES=3
6379 NUMDIRS=3
6380 setup_56() {
6381         local local_tdir="$1"
6382         local local_numfiles="$2"
6383         local local_numdirs="$3"
6384         local dir_params="$4"
6385         local dir_stripe_params="$5"
6386
6387         if [ ! -d "$local_tdir" ] ; then
6388                 test_mkdir -p $dir_stripe_params $local_tdir
6389                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6390                 for i in $(seq $local_numfiles) ; do
6391                         touch $local_tdir/file$i
6392                 done
6393                 for i in $(seq $local_numdirs) ; do
6394                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6395                         for j in $(seq $local_numfiles) ; do
6396                                 touch $local_tdir/dir$i/file$j
6397                         done
6398                 done
6399         fi
6400 }
6401
6402 setup_56_special() {
6403         local local_tdir=$1
6404         local local_numfiles=$2
6405         local local_numdirs=$3
6406
6407         setup_56 $local_tdir $local_numfiles $local_numdirs
6408
6409         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6410                 for i in $(seq $local_numfiles) ; do
6411                         mknod $local_tdir/loop${i}b b 7 $i
6412                         mknod $local_tdir/null${i}c c 1 3
6413                         ln -s $local_tdir/file1 $local_tdir/link${i}
6414                 done
6415                 for i in $(seq $local_numdirs) ; do
6416                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6417                         mknod $local_tdir/dir$i/null${i}c c 1 3
6418                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6419                 done
6420         fi
6421 }
6422
6423 test_56g() {
6424         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6425         local expected=$(($NUMDIRS + 2))
6426
6427         setup_56 $dir $NUMFILES $NUMDIRS
6428
6429         # test lfs find with -name
6430         for i in $(seq $NUMFILES) ; do
6431                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6432
6433                 [ $nums -eq $expected ] ||
6434                         error "lfs find -name '*$i' $dir wrong: "\
6435                               "found $nums, expected $expected"
6436         done
6437 }
6438 run_test 56g "check lfs find -name"
6439
6440 test_56h() {
6441         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6442         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6443
6444         setup_56 $dir $NUMFILES $NUMDIRS
6445
6446         # test lfs find with ! -name
6447         for i in $(seq $NUMFILES) ; do
6448                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6449
6450                 [ $nums -eq $expected ] ||
6451                         error "lfs find ! -name '*$i' $dir wrong: "\
6452                               "found $nums, expected $expected"
6453         done
6454 }
6455 run_test 56h "check lfs find ! -name"
6456
6457 test_56i() {
6458         local dir=$DIR/$tdir
6459
6460         test_mkdir $dir
6461
6462         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6463         local out=$($cmd)
6464
6465         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6466 }
6467 run_test 56i "check 'lfs find -ost UUID' skips directories"
6468
6469 test_56j() {
6470         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6471
6472         setup_56_special $dir $NUMFILES $NUMDIRS
6473
6474         local expected=$((NUMDIRS + 1))
6475         local cmd="$LFS find -type d $dir"
6476         local nums=$($cmd | wc -l)
6477
6478         [ $nums -eq $expected ] ||
6479                 error "'$cmd' wrong: found $nums, expected $expected"
6480 }
6481 run_test 56j "check lfs find -type d"
6482
6483 test_56k() {
6484         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6485
6486         setup_56_special $dir $NUMFILES $NUMDIRS
6487
6488         local expected=$(((NUMDIRS + 1) * NUMFILES))
6489         local cmd="$LFS find -type f $dir"
6490         local nums=$($cmd | wc -l)
6491
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494 }
6495 run_test 56k "check lfs find -type f"
6496
6497 test_56l() {
6498         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6499
6500         setup_56_special $dir $NUMFILES $NUMDIRS
6501
6502         local expected=$((NUMDIRS + NUMFILES))
6503         local cmd="$LFS find -type b $dir"
6504         local nums=$($cmd | wc -l)
6505
6506         [ $nums -eq $expected ] ||
6507                 error "'$cmd' wrong: found $nums, expected $expected"
6508 }
6509 run_test 56l "check lfs find -type b"
6510
6511 test_56m() {
6512         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6513
6514         setup_56_special $dir $NUMFILES $NUMDIRS
6515
6516         local expected=$((NUMDIRS + NUMFILES))
6517         local cmd="$LFS find -type c $dir"
6518         local nums=$($cmd | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521 }
6522 run_test 56m "check lfs find -type c"
6523
6524 test_56n() {
6525         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6526         setup_56_special $dir $NUMFILES $NUMDIRS
6527
6528         local expected=$((NUMDIRS + NUMFILES))
6529         local cmd="$LFS find -type l $dir"
6530         local nums=$($cmd | wc -l)
6531
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534 }
6535 run_test 56n "check lfs find -type l"
6536
6537 test_56o() {
6538         local dir=$DIR/$tdir
6539
6540         setup_56 $dir $NUMFILES $NUMDIRS
6541         utime $dir/file1 > /dev/null || error "utime (1)"
6542         utime $dir/file2 > /dev/null || error "utime (2)"
6543         utime $dir/dir1 > /dev/null || error "utime (3)"
6544         utime $dir/dir2 > /dev/null || error "utime (4)"
6545         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6546         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6547
6548         local expected=4
6549         local nums=$($LFS find -mtime +0 $dir | wc -l)
6550
6551         [ $nums -eq $expected ] ||
6552                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6553
6554         expected=12
6555         cmd="$LFS find -mtime 0 $dir"
6556         nums=$($cmd | wc -l)
6557         [ $nums -eq $expected ] ||
6558                 error "'$cmd' wrong: found $nums, expected $expected"
6559 }
6560 run_test 56o "check lfs find -mtime for old files"
6561
6562 test_56ob() {
6563         local dir=$DIR/$tdir
6564         local expected=1
6565         local count=0
6566
6567         # just to make sure there is something that won't be found
6568         test_mkdir $dir
6569         touch $dir/$tfile.now
6570
6571         for age in year week day hour min; do
6572                 count=$((count + 1))
6573
6574                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6575                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6576                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6577
6578                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6579                 local nums=$($cmd | wc -l)
6580                 [ $nums -eq $expected ] ||
6581                         error "'$cmd' wrong: found $nums, expected $expected"
6582
6583                 cmd="$LFS find $dir -atime $count${age:0:1}"
6584                 nums=$($cmd | wc -l)
6585                 [ $nums -eq $expected ] ||
6586                         error "'$cmd' wrong: found $nums, expected $expected"
6587         done
6588
6589         sleep 2
6590         cmd="$LFS find $dir -ctime +1s -type f"
6591         nums=$($cmd | wc -l)
6592         (( $nums == $count * 2 + 1)) ||
6593                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6594 }
6595 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6596
6597 test_newerXY_base() {
6598         local x=$1
6599         local y=$2
6600         local dir=$DIR/$tdir
6601         local ref
6602         local negref
6603
6604         if [ $y == "t" ]; then
6605                 if [ $x == "b" ]; then
6606                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6607                 else
6608                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6609                 fi
6610         else
6611                 ref=$DIR/$tfile.newer.$x$y
6612                 touch $ref || error "touch $ref failed"
6613         fi
6614
6615         echo "before = $ref"
6616         sleep 2
6617         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6618         sleep 2
6619         if [ $y == "t" ]; then
6620                 if [ $x == "b" ]; then
6621                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6622                 else
6623                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6624                 fi
6625         else
6626                 negref=$DIR/$tfile.negnewer.$x$y
6627                 touch $negref || error "touch $negref failed"
6628         fi
6629
6630         echo "after = $negref"
6631         local cmd="$LFS find $dir -newer$x$y $ref"
6632         local nums=$(eval $cmd | wc -l)
6633         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6634
6635         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6636                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6637
6638         cmd="$LFS find $dir ! -newer$x$y $negref"
6639         nums=$(eval $cmd | wc -l)
6640         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6641                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6642
6643         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6644         nums=$(eval $cmd | wc -l)
6645         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6646                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6647
6648         rm -rf $DIR/*
6649 }
6650
6651 test_56oc() {
6652         test_newerXY_base "a" "a"
6653         test_newerXY_base "a" "m"
6654         test_newerXY_base "a" "c"
6655         test_newerXY_base "m" "a"
6656         test_newerXY_base "m" "m"
6657         test_newerXY_base "m" "c"
6658         test_newerXY_base "c" "a"
6659         test_newerXY_base "c" "m"
6660         test_newerXY_base "c" "c"
6661
6662         [[ -n "$sles_version" ]] &&
6663                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6664
6665         test_newerXY_base "a" "t"
6666         test_newerXY_base "m" "t"
6667         test_newerXY_base "c" "t"
6668
6669         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6670            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6671                 ! btime_supported && echo "btime unsupported" && return 0
6672
6673         test_newerXY_base "b" "b"
6674         test_newerXY_base "b" "t"
6675 }
6676 run_test 56oc "check lfs find -newerXY work"
6677
6678 btime_supported() {
6679         local dir=$DIR/$tdir
6680         local rc
6681
6682         mkdir -p $dir
6683         touch $dir/$tfile
6684         $LFS find $dir -btime -1d -type f
6685         rc=$?
6686         rm -rf $dir
6687         return $rc
6688 }
6689
6690 test_56od() {
6691         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6692                 ! btime_supported && skip "btime unsupported on MDS"
6693
6694         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6695                 ! btime_supported && skip "btime unsupported on clients"
6696
6697         local dir=$DIR/$tdir
6698         local ref=$DIR/$tfile.ref
6699         local negref=$DIR/$tfile.negref
6700
6701         mkdir $dir || error "mkdir $dir failed"
6702         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6703         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6704         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6705         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6706         touch $ref || error "touch $ref failed"
6707         # sleep 3 seconds at least
6708         sleep 3
6709
6710         local before=$(do_facet mds1 date +%s)
6711         local skew=$(($(date +%s) - before + 1))
6712
6713         if (( skew < 0 && skew > -5 )); then
6714                 sleep $((0 - skew + 1))
6715                 skew=0
6716         fi
6717
6718         # Set the dir stripe params to limit files all on MDT0,
6719         # otherwise we need to calc the max clock skew between
6720         # the client and MDTs.
6721         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6722         sleep 2
6723         touch $negref || error "touch $negref failed"
6724
6725         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6726         local nums=$($cmd | wc -l)
6727         local expected=$(((NUMFILES + 1) * NUMDIRS))
6728
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731
6732         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6733         nums=$($cmd | wc -l)
6734         expected=$((NUMFILES + 1))
6735         [ $nums -eq $expected ] ||
6736                 error "'$cmd' wrong: found $nums, expected $expected"
6737
6738         [ $skew -lt 0 ] && return
6739
6740         local after=$(do_facet mds1 date +%s)
6741         local age=$((after - before + 1 + skew))
6742
6743         cmd="$LFS find $dir -btime -${age}s -type f"
6744         nums=$($cmd | wc -l)
6745         expected=$(((NUMFILES + 1) * NUMDIRS))
6746
6747         echo "Clock skew between client and server: $skew, age:$age"
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=$(($NUMDIRS + 1))
6752         cmd="$LFS find $dir -btime -${age}s -type d"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         rm -f $ref $negref || error "Failed to remove $ref $negref"
6757 }
6758 run_test 56od "check lfs find -btime with units"
6759
6760 test_56p() {
6761         [ $RUNAS_ID -eq $UID ] &&
6762                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6763
6764         local dir=$DIR/$tdir
6765
6766         setup_56 $dir $NUMFILES $NUMDIRS
6767         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6768
6769         local expected=$NUMFILES
6770         local cmd="$LFS find -uid $RUNAS_ID $dir"
6771         local nums=$($cmd | wc -l)
6772
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6777         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781 }
6782 run_test 56p "check lfs find -uid and ! -uid"
6783
6784 test_56q() {
6785         [ $RUNAS_ID -eq $UID ] &&
6786                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6787
6788         local dir=$DIR/$tdir
6789
6790         setup_56 $dir $NUMFILES $NUMDIRS
6791         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6792
6793         local expected=$NUMFILES
6794         local cmd="$LFS find -gid $RUNAS_GID $dir"
6795         local nums=$($cmd | wc -l)
6796
6797         [ $nums -eq $expected ] ||
6798                 error "'$cmd' wrong: found $nums, expected $expected"
6799
6800         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6801         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805 }
6806 run_test 56q "check lfs find -gid and ! -gid"
6807
6808 test_56r() {
6809         local dir=$DIR/$tdir
6810
6811         setup_56 $dir $NUMFILES $NUMDIRS
6812
6813         local expected=12
6814         local cmd="$LFS find -size 0 -type f -lazy $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819         cmd="$LFS find -size 0 -type f $dir"
6820         nums=$($cmd | wc -l)
6821         [ $nums -eq $expected ] ||
6822                 error "'$cmd' wrong: found $nums, expected $expected"
6823
6824         expected=0
6825         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6826         nums=$($cmd | wc -l)
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829         cmd="$LFS find ! -size 0 -type f $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         echo "test" > $dir/$tfile
6835         echo "test2" > $dir/$tfile.2 && sync
6836         expected=1
6837         cmd="$LFS find -size 5 -type f -lazy $dir"
6838         nums=$($cmd | wc -l)
6839         [ $nums -eq $expected ] ||
6840                 error "'$cmd' wrong: found $nums, expected $expected"
6841         cmd="$LFS find -size 5 -type f $dir"
6842         nums=$($cmd | wc -l)
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845
6846         expected=1
6847         cmd="$LFS find -size +5 -type f -lazy $dir"
6848         nums=$($cmd | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851         cmd="$LFS find -size +5 -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855
6856         expected=2
6857         cmd="$LFS find -size +0 -type f -lazy $dir"
6858         nums=$($cmd | wc -l)
6859         [ $nums -eq $expected ] ||
6860                 error "'$cmd' wrong: found $nums, expected $expected"
6861         cmd="$LFS find -size +0 -type f $dir"
6862         nums=$($cmd | wc -l)
6863         [ $nums -eq $expected ] ||
6864                 error "'$cmd' wrong: found $nums, expected $expected"
6865
6866         expected=2
6867         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871         cmd="$LFS find ! -size -5 -type f $dir"
6872         nums=$($cmd | wc -l)
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875
6876         expected=12
6877         cmd="$LFS find -size -5 -type f -lazy $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881         cmd="$LFS find -size -5 -type f $dir"
6882         nums=$($cmd | wc -l)
6883         [ $nums -eq $expected ] ||
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885 }
6886 run_test 56r "check lfs find -size works"
6887
6888 test_56ra_sub() {
6889         local expected=$1
6890         local glimpses=$2
6891         local cmd="$3"
6892
6893         cancel_lru_locks $OSC
6894
6895         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6896         local nums=$($cmd | wc -l)
6897
6898         [ $nums -eq $expected ] ||
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900
6901         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6902
6903         if (( rpcs_before + glimpses != rpcs_after )); then
6904                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6905                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6906
6907                 if [[ $glimpses == 0 ]]; then
6908                         error "'$cmd' should not send glimpse RPCs to OST"
6909                 else
6910                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6911                 fi
6912         fi
6913 }
6914
6915 test_56ra() {
6916         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6917                 skip "MDS < 2.12.58 doesn't return LSOM data"
6918         local dir=$DIR/$tdir
6919         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6920
6921         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6922
6923         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6924         $LCTL set_param -n llite.*.statahead_agl=0
6925         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6926
6927         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6928         # open and close all files to ensure LSOM is updated
6929         cancel_lru_locks $OSC
6930         find $dir -type f | xargs cat > /dev/null
6931
6932         #   expect_found  glimpse_rpcs  command_to_run
6933         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6934         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6935         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6936         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6937
6938         echo "test" > $dir/$tfile
6939         echo "test2" > $dir/$tfile.2 && sync
6940         cancel_lru_locks $OSC
6941         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6942
6943         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6944         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6945         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6946         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6947
6948         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6949         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6950         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6951         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6952         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6953         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6954 }
6955 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6956
6957 test_56rb() {
6958         local dir=$DIR/$tdir
6959         local tmp=$TMP/$tfile.log
6960         local mdt_idx;
6961
6962         test_mkdir -p $dir || error "failed to mkdir $dir"
6963         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6964                 error "failed to setstripe $dir/$tfile"
6965         mdt_idx=$($LFS getdirstripe -i $dir)
6966         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6967
6968         stack_trap "rm -f $tmp" EXIT
6969         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6970         ! grep -q obd_uuid $tmp ||
6971                 error "failed to find --size +100K --ost 0 $dir"
6972         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6973         ! grep -q obd_uuid $tmp ||
6974                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6975 }
6976 run_test 56rb "check lfs find --size --ost/--mdt works"
6977
6978 test_56rc() {
6979         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6980         local dir=$DIR/$tdir
6981         local found
6982
6983         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6984         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6985         (( $MDSCOUNT > 2 )) &&
6986                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6987         mkdir $dir/$tdir-{1..10}
6988         touch $dir/$tfile-{1..10}
6989
6990         found=$($LFS find $dir --mdt-count 2 | wc -l)
6991         expect=11
6992         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6993
6994         found=$($LFS find $dir -T +1 | wc -l)
6995         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6996         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6997
6998         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6999         expect=11
7000         (( $found == $expect )) || error "found $found all_char, expect $expect"
7001
7002         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7003         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7004         (( $found == $expect )) || error "found $found all_char, expect $expect"
7005 }
7006 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7007
7008 test_56s() { # LU-611 #LU-9369
7009         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7010
7011         local dir=$DIR/$tdir
7012         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7013
7014         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7015         for i in $(seq $NUMDIRS); do
7016                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7017         done
7018
7019         local expected=$NUMDIRS
7020         local cmd="$LFS find -c $OSTCOUNT $dir"
7021         local nums=$($cmd | wc -l)
7022
7023         [ $nums -eq $expected ] || {
7024                 $LFS getstripe -R $dir
7025                 error "'$cmd' wrong: found $nums, expected $expected"
7026         }
7027
7028         expected=$((NUMDIRS + onestripe))
7029         cmd="$LFS find -stripe-count +0 -type f $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] || {
7032                 $LFS getstripe -R $dir
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034         }
7035
7036         expected=$onestripe
7037         cmd="$LFS find -stripe-count 1 -type f $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] || {
7040                 $LFS getstripe -R $dir
7041                 error "'$cmd' wrong: found $nums, expected $expected"
7042         }
7043
7044         cmd="$LFS find -stripe-count -2 -type f $dir"
7045         nums=$($cmd | wc -l)
7046         [ $nums -eq $expected ] || {
7047                 $LFS getstripe -R $dir
7048                 error "'$cmd' wrong: found $nums, expected $expected"
7049         }
7050
7051         expected=0
7052         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7053         nums=$($cmd | wc -l)
7054         [ $nums -eq $expected ] || {
7055                 $LFS getstripe -R $dir
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057         }
7058 }
7059 run_test 56s "check lfs find -stripe-count works"
7060
7061 test_56t() { # LU-611 #LU-9369
7062         local dir=$DIR/$tdir
7063
7064         setup_56 $dir 0 $NUMDIRS
7065         for i in $(seq $NUMDIRS); do
7066                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7067         done
7068
7069         local expected=$NUMDIRS
7070         local cmd="$LFS find -S 8M $dir"
7071         local nums=$($cmd | wc -l)
7072
7073         [ $nums -eq $expected ] || {
7074                 $LFS getstripe -R $dir
7075                 error "'$cmd' wrong: found $nums, expected $expected"
7076         }
7077         rm -rf $dir
7078
7079         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7080
7081         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7082
7083         expected=$(((NUMDIRS + 1) * NUMFILES))
7084         cmd="$LFS find -stripe-size 512k -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088
7089         cmd="$LFS find -stripe-size +320k -type f $dir"
7090         nums=$($cmd | wc -l)
7091         [ $nums -eq $expected ] ||
7092                 error "'$cmd' wrong: found $nums, expected $expected"
7093
7094         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7095         cmd="$LFS find -stripe-size +200k -type f $dir"
7096         nums=$($cmd | wc -l)
7097         [ $nums -eq $expected ] ||
7098                 error "'$cmd' wrong: found $nums, expected $expected"
7099
7100         cmd="$LFS find -stripe-size -640k -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=4
7106         cmd="$LFS find -stripe-size 256k -type f $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110
7111         cmd="$LFS find -stripe-size -320k -type f $dir"
7112         nums=$($cmd | wc -l)
7113         [ $nums -eq $expected ] ||
7114                 error "'$cmd' wrong: found $nums, expected $expected"
7115
7116         expected=0
7117         cmd="$LFS find -stripe-size 1024k -type f $dir"
7118         nums=$($cmd | wc -l)
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121 }
7122 run_test 56t "check lfs find -stripe-size works"
7123
7124 test_56u() { # LU-611
7125         local dir=$DIR/$tdir
7126
7127         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7128
7129         if [[ $OSTCOUNT -gt 1 ]]; then
7130                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7131                 onestripe=4
7132         else
7133                 onestripe=0
7134         fi
7135
7136         local expected=$(((NUMDIRS + 1) * NUMFILES))
7137         local cmd="$LFS find -stripe-index 0 -type f $dir"
7138         local nums=$($cmd | wc -l)
7139
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         expected=$onestripe
7144         cmd="$LFS find -stripe-index 1 -type f $dir"
7145         nums=$($cmd | wc -l)
7146         [ $nums -eq $expected ] ||
7147                 error "'$cmd' wrong: found $nums, expected $expected"
7148
7149         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153
7154         expected=0
7155         # This should produce an error and not return any files
7156         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7157         nums=$($cmd 2>/dev/null | wc -l)
7158         [ $nums -eq $expected ] ||
7159                 error "'$cmd' wrong: found $nums, expected $expected"
7160
7161         if [[ $OSTCOUNT -gt 1 ]]; then
7162                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7163                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7164                 nums=$($cmd | wc -l)
7165                 [ $nums -eq $expected ] ||
7166                         error "'$cmd' wrong: found $nums, expected $expected"
7167         fi
7168 }
7169 run_test 56u "check lfs find -stripe-index works"
7170
7171 test_56v() {
7172         local mdt_idx=0
7173         local dir=$DIR/$tdir
7174
7175         setup_56 $dir $NUMFILES $NUMDIRS
7176
7177         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7178         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7179
7180         for file in $($LFS find -m $UUID $dir); do
7181                 file_midx=$($LFS getstripe -m $file)
7182                 [ $file_midx -eq $mdt_idx ] ||
7183                         error "lfs find -m $UUID != getstripe -m $file_midx"
7184         done
7185 }
7186 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7187
7188 test_56w() {
7189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7191
7192         local dir=$DIR/$tdir
7193
7194         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7195
7196         local stripe_size=$($LFS getstripe -S -d $dir) ||
7197                 error "$LFS getstripe -S -d $dir failed"
7198         stripe_size=${stripe_size%% *}
7199
7200         local file_size=$((stripe_size * OSTCOUNT))
7201         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7202         local required_space=$((file_num * file_size))
7203         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7204                            head -n1)
7205         [[ $free_space -le $((required_space / 1024)) ]] &&
7206                 skip_env "need $required_space, have $free_space kbytes"
7207
7208         local dd_bs=65536
7209         local dd_count=$((file_size / dd_bs))
7210
7211         # write data into the files
7212         local i
7213         local j
7214         local file
7215
7216         for i in $(seq $NUMFILES); do
7217                 file=$dir/file$i
7218                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7219                         error "write data into $file failed"
7220         done
7221         for i in $(seq $NUMDIRS); do
7222                 for j in $(seq $NUMFILES); do
7223                         file=$dir/dir$i/file$j
7224                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7225                                 error "write data into $file failed"
7226                 done
7227         done
7228
7229         # $LFS_MIGRATE will fail if hard link migration is unsupported
7230         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7231                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7232                         error "creating links to $dir/dir1/file1 failed"
7233         fi
7234
7235         local expected=-1
7236
7237         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7238
7239         # lfs_migrate file
7240         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7241
7242         echo "$cmd"
7243         eval $cmd || error "$cmd failed"
7244
7245         check_stripe_count $dir/file1 $expected
7246
7247         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7248         then
7249                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7250                 # OST 1 if it is on OST 0. This file is small enough to
7251                 # be on only one stripe.
7252                 file=$dir/migr_1_ost
7253                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7254                         error "write data into $file failed"
7255                 local obdidx=$($LFS getstripe -i $file)
7256                 local oldmd5=$(md5sum $file)
7257                 local newobdidx=0
7258
7259                 [[ $obdidx -eq 0 ]] && newobdidx=1
7260                 cmd="$LFS migrate -i $newobdidx $file"
7261                 echo $cmd
7262                 eval $cmd || error "$cmd failed"
7263
7264                 local realobdix=$($LFS getstripe -i $file)
7265                 local newmd5=$(md5sum $file)
7266
7267                 [[ $newobdidx -ne $realobdix ]] &&
7268                         error "new OST is different (was=$obdidx, "\
7269                               "wanted=$newobdidx, got=$realobdix)"
7270                 [[ "$oldmd5" != "$newmd5" ]] &&
7271                         error "md5sum differ: $oldmd5, $newmd5"
7272         fi
7273
7274         # lfs_migrate dir
7275         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7276         echo "$cmd"
7277         eval $cmd || error "$cmd failed"
7278
7279         for j in $(seq $NUMFILES); do
7280                 check_stripe_count $dir/dir1/file$j $expected
7281         done
7282
7283         # lfs_migrate works with lfs find
7284         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7285              $LFS_MIGRATE -y -c $expected"
7286         echo "$cmd"
7287         eval $cmd || error "$cmd failed"
7288
7289         for i in $(seq 2 $NUMFILES); do
7290                 check_stripe_count $dir/file$i $expected
7291         done
7292         for i in $(seq 2 $NUMDIRS); do
7293                 for j in $(seq $NUMFILES); do
7294                 check_stripe_count $dir/dir$i/file$j $expected
7295                 done
7296         done
7297 }
7298 run_test 56w "check lfs_migrate -c stripe_count works"
7299
7300 test_56wb() {
7301         local file1=$DIR/$tdir/file1
7302         local create_pool=false
7303         local initial_pool=$($LFS getstripe -p $DIR)
7304         local pool_list=()
7305         local pool=""
7306
7307         echo -n "Creating test dir..."
7308         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7309         echo "done."
7310
7311         echo -n "Creating test file..."
7312         touch $file1 || error "cannot create file"
7313         echo "done."
7314
7315         echo -n "Detecting existing pools..."
7316         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7317
7318         if [ ${#pool_list[@]} -gt 0 ]; then
7319                 echo "${pool_list[@]}"
7320                 for thispool in "${pool_list[@]}"; do
7321                         if [[ -z "$initial_pool" ||
7322                               "$initial_pool" != "$thispool" ]]; then
7323                                 pool="$thispool"
7324                                 echo "Using existing pool '$pool'"
7325                                 break
7326                         fi
7327                 done
7328         else
7329                 echo "none detected."
7330         fi
7331         if [ -z "$pool" ]; then
7332                 pool=${POOL:-testpool}
7333                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7334                 echo -n "Creating pool '$pool'..."
7335                 create_pool=true
7336                 pool_add $pool &> /dev/null ||
7337                         error "pool_add failed"
7338                 echo "done."
7339
7340                 echo -n "Adding target to pool..."
7341                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7342                         error "pool_add_targets failed"
7343                 echo "done."
7344         fi
7345
7346         echo -n "Setting pool using -p option..."
7347         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7348                 error "migrate failed rc = $?"
7349         echo "done."
7350
7351         echo -n "Verifying test file is in pool after migrating..."
7352         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7353                 error "file was not migrated to pool $pool"
7354         echo "done."
7355
7356         echo -n "Removing test file from pool '$pool'..."
7357         # "lfs migrate $file" won't remove the file from the pool
7358         # until some striping information is changed.
7359         $LFS migrate -c 1 $file1 &> /dev/null ||
7360                 error "cannot remove from pool"
7361         [ "$($LFS getstripe -p $file1)" ] &&
7362                 error "pool still set"
7363         echo "done."
7364
7365         echo -n "Setting pool using --pool option..."
7366         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7367                 error "migrate failed rc = $?"
7368         echo "done."
7369
7370         # Clean up
7371         rm -f $file1
7372         if $create_pool; then
7373                 destroy_test_pools 2> /dev/null ||
7374                         error "destroy test pools failed"
7375         fi
7376 }
7377 run_test 56wb "check lfs_migrate pool support"
7378
7379 test_56wc() {
7380         local file1="$DIR/$tdir/file1"
7381         local parent_ssize
7382         local parent_scount
7383         local cur_ssize
7384         local cur_scount
7385         local orig_ssize
7386
7387         echo -n "Creating test dir..."
7388         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7389         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7390                 error "cannot set stripe by '-S 1M -c 1'"
7391         echo "done"
7392
7393         echo -n "Setting initial stripe for test file..."
7394         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7395                 error "cannot set stripe"
7396         cur_ssize=$($LFS getstripe -S "$file1")
7397         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7398         echo "done."
7399
7400         # File currently set to -S 512K -c 1
7401
7402         # Ensure -c and -S options are rejected when -R is set
7403         echo -n "Verifying incompatible options are detected..."
7404         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7405                 error "incompatible -c and -R options not detected"
7406         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7407                 error "incompatible -S and -R options not detected"
7408         echo "done."
7409
7410         # Ensure unrecognized options are passed through to 'lfs migrate'
7411         echo -n "Verifying -S option is passed through to lfs migrate..."
7412         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7413                 error "migration failed"
7414         cur_ssize=$($LFS getstripe -S "$file1")
7415         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7416         echo "done."
7417
7418         # File currently set to -S 1M -c 1
7419
7420         # Ensure long options are supported
7421         echo -n "Verifying long options supported..."
7422         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7423                 error "long option without argument not supported"
7424         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7425                 error "long option with argument not supported"
7426         cur_ssize=$($LFS getstripe -S "$file1")
7427         [ $cur_ssize -eq 524288 ] ||
7428                 error "migrate --stripe-size $cur_ssize != 524288"
7429         echo "done."
7430
7431         # File currently set to -S 512K -c 1
7432
7433         if [ "$OSTCOUNT" -gt 1 ]; then
7434                 echo -n "Verifying explicit stripe count can be set..."
7435                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7436                         error "migrate failed"
7437                 cur_scount=$($LFS getstripe -c "$file1")
7438                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7439                 echo "done."
7440         fi
7441
7442         # File currently set to -S 512K -c 1 or -S 512K -c 2
7443
7444         # Ensure parent striping is used if -R is set, and no stripe
7445         # count or size is specified
7446         echo -n "Setting stripe for parent directory..."
7447         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7448                 error "cannot set stripe '-S 2M -c 1'"
7449         echo "done."
7450
7451         echo -n "Verifying restripe option uses parent stripe settings..."
7452         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7453         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7454         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7455                 error "migrate failed"
7456         cur_ssize=$($LFS getstripe -S "$file1")
7457         [ $cur_ssize -eq $parent_ssize ] ||
7458                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7459         cur_scount=$($LFS getstripe -c "$file1")
7460         [ $cur_scount -eq $parent_scount ] ||
7461                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7462         echo "done."
7463
7464         # File currently set to -S 1M -c 1
7465
7466         # Ensure striping is preserved if -R is not set, and no stripe
7467         # count or size is specified
7468         echo -n "Verifying striping size preserved when not specified..."
7469         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7470         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7471                 error "cannot set stripe on parent directory"
7472         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7473                 error "migrate failed"
7474         cur_ssize=$($LFS getstripe -S "$file1")
7475         [ $cur_ssize -eq $orig_ssize ] ||
7476                 error "migrate by default $cur_ssize != $orig_ssize"
7477         echo "done."
7478
7479         # Ensure file name properly detected when final option has no argument
7480         echo -n "Verifying file name properly detected..."
7481         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7482                 error "file name interpreted as option argument"
7483         echo "done."
7484
7485         # Clean up
7486         rm -f "$file1"
7487 }
7488 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7489
7490 test_56wd() {
7491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7492
7493         local file1=$DIR/$tdir/file1
7494
7495         echo -n "Creating test dir..."
7496         test_mkdir $DIR/$tdir || error "cannot create dir"
7497         echo "done."
7498
7499         echo -n "Creating test file..."
7500         touch $file1
7501         echo "done."
7502
7503         # Ensure 'lfs migrate' will fail by using a non-existent option,
7504         # and make sure rsync is not called to recover
7505         echo -n "Make sure --no-rsync option works..."
7506         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7507                 grep -q 'refusing to fall back to rsync' ||
7508                 error "rsync was called with --no-rsync set"
7509         echo "done."
7510
7511         # Ensure rsync is called without trying 'lfs migrate' first
7512         echo -n "Make sure --rsync option works..."
7513         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7514                 grep -q 'falling back to rsync' &&
7515                 error "lfs migrate was called with --rsync set"
7516         echo "done."
7517
7518         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7519         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7520                 grep -q 'at the same time' ||
7521                 error "--rsync and --no-rsync accepted concurrently"
7522         echo "done."
7523
7524         # Clean up
7525         rm -f $file1
7526 }
7527 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7528
7529 test_56we() {
7530         local td=$DIR/$tdir
7531         local tf=$td/$tfile
7532
7533         test_mkdir $td || error "cannot create $td"
7534         touch $tf || error "cannot touch $tf"
7535
7536         echo -n "Make sure --non-direct|-D works..."
7537         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7538                 grep -q "lfs migrate --non-direct" ||
7539                 error "--non-direct option cannot work correctly"
7540         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7541                 grep -q "lfs migrate -D" ||
7542                 error "-D option cannot work correctly"
7543         echo "done."
7544 }
7545 run_test 56we "check lfs_migrate --non-direct|-D support"
7546
7547 test_56x() {
7548         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7549         check_swap_layouts_support
7550
7551         local dir=$DIR/$tdir
7552         local ref1=/etc/passwd
7553         local file1=$dir/file1
7554
7555         test_mkdir $dir || error "creating dir $dir"
7556         $LFS setstripe -c 2 $file1
7557         cp $ref1 $file1
7558         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7559         stripe=$($LFS getstripe -c $file1)
7560         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7561         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7562
7563         # clean up
7564         rm -f $file1
7565 }
7566 run_test 56x "lfs migration support"
7567
7568 test_56xa() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570         check_swap_layouts_support
7571
7572         local dir=$DIR/$tdir/$testnum
7573
7574         test_mkdir -p $dir
7575
7576         local ref1=/etc/passwd
7577         local file1=$dir/file1
7578
7579         $LFS setstripe -c 2 $file1
7580         cp $ref1 $file1
7581         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7582
7583         local stripe=$($LFS getstripe -c $file1)
7584
7585         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7586         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7587
7588         # clean up
7589         rm -f $file1
7590 }
7591 run_test 56xa "lfs migration --block support"
7592
7593 check_migrate_links() {
7594         local dir="$1"
7595         local file1="$dir/file1"
7596         local begin="$2"
7597         local count="$3"
7598         local runas="$4"
7599         local total_count=$(($begin + $count - 1))
7600         local symlink_count=10
7601         local uniq_count=10
7602
7603         if [ ! -f "$file1" ]; then
7604                 echo -n "creating initial file..."
7605                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7606                         error "cannot setstripe initial file"
7607                 echo "done"
7608
7609                 echo -n "creating symlinks..."
7610                 for s in $(seq 1 $symlink_count); do
7611                         ln -s "$file1" "$dir/slink$s" ||
7612                                 error "cannot create symlinks"
7613                 done
7614                 echo "done"
7615
7616                 echo -n "creating nonlinked files..."
7617                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7618                         error "cannot create nonlinked files"
7619                 echo "done"
7620         fi
7621
7622         # create hard links
7623         if [ ! -f "$dir/file$total_count" ]; then
7624                 echo -n "creating hard links $begin:$total_count..."
7625                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7626                         /dev/null || error "cannot create hard links"
7627                 echo "done"
7628         fi
7629
7630         echo -n "checking number of hard links listed in xattrs..."
7631         local fid=$($LFS getstripe -F "$file1")
7632         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7633
7634         echo "${#paths[*]}"
7635         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7636                         skip "hard link list has unexpected size, skipping test"
7637         fi
7638         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7639                         error "link names should exceed xattrs size"
7640         fi
7641
7642         echo -n "migrating files..."
7643         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7644         local rc=$?
7645         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7646         echo "done"
7647
7648         # make sure all links have been properly migrated
7649         echo -n "verifying files..."
7650         fid=$($LFS getstripe -F "$file1") ||
7651                 error "cannot get fid for file $file1"
7652         for i in $(seq 2 $total_count); do
7653                 local fid2=$($LFS getstripe -F $dir/file$i)
7654
7655                 [ "$fid2" == "$fid" ] ||
7656                         error "migrated hard link has mismatched FID"
7657         done
7658
7659         # make sure hard links were properly detected, and migration was
7660         # performed only once for the entire link set; nonlinked files should
7661         # also be migrated
7662         local actual=$(grep -c 'done' <<< "$migrate_out")
7663         local expected=$(($uniq_count + 1))
7664
7665         [ "$actual" -eq  "$expected" ] ||
7666                 error "hard links individually migrated ($actual != $expected)"
7667
7668         # make sure the correct number of hard links are present
7669         local hardlinks=$(stat -c '%h' "$file1")
7670
7671         [ $hardlinks -eq $total_count ] ||
7672                 error "num hard links $hardlinks != $total_count"
7673         echo "done"
7674
7675         return 0
7676 }
7677
7678 test_56xb() {
7679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7680                 skip "Need MDS version at least 2.10.55"
7681
7682         local dir="$DIR/$tdir"
7683
7684         test_mkdir "$dir" || error "cannot create dir $dir"
7685
7686         echo "testing lfs migrate mode when all links fit within xattrs"
7687         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7688
7689         echo "testing rsync mode when all links fit within xattrs"
7690         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7691
7692         echo "testing lfs migrate mode when all links do not fit within xattrs"
7693         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7694
7695         echo "testing rsync mode when all links do not fit within xattrs"
7696         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7697
7698         chown -R $RUNAS_ID $dir
7699         echo "testing non-root lfs migrate mode when not all links are in xattr"
7700         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7701
7702         # clean up
7703         rm -rf $dir
7704 }
7705 run_test 56xb "lfs migration hard link support"
7706
7707 test_56xc() {
7708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7709
7710         local dir="$DIR/$tdir"
7711
7712         test_mkdir "$dir" || error "cannot create dir $dir"
7713
7714         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7715         echo -n "Setting initial stripe for 20MB test file..."
7716         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7717                 error "cannot setstripe 20MB file"
7718         echo "done"
7719         echo -n "Sizing 20MB test file..."
7720         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7721         echo "done"
7722         echo -n "Verifying small file autostripe count is 1..."
7723         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7724                 error "cannot migrate 20MB file"
7725         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7726                 error "cannot get stripe for $dir/20mb"
7727         [ $stripe_count -eq 1 ] ||
7728                 error "unexpected stripe count $stripe_count for 20MB file"
7729         rm -f "$dir/20mb"
7730         echo "done"
7731
7732         # Test 2: File is small enough to fit within the available space on
7733         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7734         # have at least an additional 1KB for each desired stripe for test 3
7735         echo -n "Setting stripe for 1GB test file..."
7736         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7737         echo "done"
7738         echo -n "Sizing 1GB test file..."
7739         # File size is 1GB + 3KB
7740         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7741         echo "done"
7742
7743         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7744         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7745         if (( avail > 524288 * OSTCOUNT )); then
7746                 echo -n "Migrating 1GB file..."
7747                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7748                         error "cannot migrate 1GB file"
7749                 echo "done"
7750                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7751                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7752                         error "cannot getstripe for 1GB file"
7753                 [ $stripe_count -eq 2 ] ||
7754                         error "unexpected stripe count $stripe_count != 2"
7755                 echo "done"
7756         fi
7757
7758         # Test 3: File is too large to fit within the available space on
7759         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7760         if [ $OSTCOUNT -ge 3 ]; then
7761                 # The required available space is calculated as
7762                 # file size (1GB + 3KB) / OST count (3).
7763                 local kb_per_ost=349526
7764
7765                 echo -n "Migrating 1GB file with limit..."
7766                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7767                         error "cannot migrate 1GB file with limit"
7768                 echo "done"
7769
7770                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7771                 echo -n "Verifying 1GB autostripe count with limited space..."
7772                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7773                         error "unexpected stripe count $stripe_count (min 3)"
7774                 echo "done"
7775         fi
7776
7777         # clean up
7778         rm -rf $dir
7779 }
7780 run_test 56xc "lfs migration autostripe"
7781
7782 test_56xd() {
7783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7784
7785         local dir=$DIR/$tdir
7786         local f_mgrt=$dir/$tfile.mgrt
7787         local f_yaml=$dir/$tfile.yaml
7788         local f_copy=$dir/$tfile.copy
7789         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7790         local layout_copy="-c 2 -S 2M -i 1"
7791         local yamlfile=$dir/yamlfile
7792         local layout_before;
7793         local layout_after;
7794
7795         test_mkdir "$dir" || error "cannot create dir $dir"
7796         $LFS setstripe $layout_yaml $f_yaml ||
7797                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7798         $LFS getstripe --yaml $f_yaml > $yamlfile
7799         $LFS setstripe $layout_copy $f_copy ||
7800                 error "cannot setstripe $f_copy with layout $layout_copy"
7801         touch $f_mgrt
7802         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7803
7804         # 1. test option --yaml
7805         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7806                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7807         layout_before=$(get_layout_param $f_yaml)
7808         layout_after=$(get_layout_param $f_mgrt)
7809         [ "$layout_after" == "$layout_before" ] ||
7810                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7811
7812         # 2. test option --copy
7813         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7814                 error "cannot migrate $f_mgrt with --copy $f_copy"
7815         layout_before=$(get_layout_param $f_copy)
7816         layout_after=$(get_layout_param $f_mgrt)
7817         [ "$layout_after" == "$layout_before" ] ||
7818                 error "lfs_migrate --copy: $layout_after != $layout_before"
7819 }
7820 run_test 56xd "check lfs_migrate --yaml and --copy support"
7821
7822 test_56xe() {
7823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7824
7825         local dir=$DIR/$tdir
7826         local f_comp=$dir/$tfile
7827         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7828         local layout_before=""
7829         local layout_after=""
7830
7831         test_mkdir "$dir" || error "cannot create dir $dir"
7832         $LFS setstripe $layout $f_comp ||
7833                 error "cannot setstripe $f_comp with layout $layout"
7834         layout_before=$(get_layout_param $f_comp)
7835         dd if=/dev/zero of=$f_comp bs=1M count=4
7836
7837         # 1. migrate a comp layout file by lfs_migrate
7838         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7839         layout_after=$(get_layout_param $f_comp)
7840         [ "$layout_before" == "$layout_after" ] ||
7841                 error "lfs_migrate: $layout_before != $layout_after"
7842
7843         # 2. migrate a comp layout file by lfs migrate
7844         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7845         layout_after=$(get_layout_param $f_comp)
7846         [ "$layout_before" == "$layout_after" ] ||
7847                 error "lfs migrate: $layout_before != $layout_after"
7848 }
7849 run_test 56xe "migrate a composite layout file"
7850
7851 test_56xf() {
7852         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7853
7854         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7855                 skip "Need server version at least 2.13.53"
7856
7857         local dir=$DIR/$tdir
7858         local f_comp=$dir/$tfile
7859         local layout="-E 1M -c1 -E -1 -c2"
7860         local fid_before=""
7861         local fid_after=""
7862
7863         test_mkdir "$dir" || error "cannot create dir $dir"
7864         $LFS setstripe $layout $f_comp ||
7865                 error "cannot setstripe $f_comp with layout $layout"
7866         fid_before=$($LFS getstripe --fid $f_comp)
7867         dd if=/dev/zero of=$f_comp bs=1M count=4
7868
7869         # 1. migrate a comp layout file to a comp layout
7870         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7871         fid_after=$($LFS getstripe --fid $f_comp)
7872         [ "$fid_before" == "$fid_after" ] ||
7873                 error "comp-to-comp migrate: $fid_before != $fid_after"
7874
7875         # 2. migrate a comp layout file to a plain layout
7876         $LFS migrate -c2 $f_comp ||
7877                 error "cannot migrate $f_comp by lfs migrate"
7878         fid_after=$($LFS getstripe --fid $f_comp)
7879         [ "$fid_before" == "$fid_after" ] ||
7880                 error "comp-to-plain migrate: $fid_before != $fid_after"
7881
7882         # 3. migrate a plain layout file to a comp layout
7883         $LFS migrate $layout $f_comp ||
7884                 error "cannot migrate $f_comp by lfs migrate"
7885         fid_after=$($LFS getstripe --fid $f_comp)
7886         [ "$fid_before" == "$fid_after" ] ||
7887                 error "plain-to-comp migrate: $fid_before != $fid_after"
7888 }
7889 run_test 56xf "FID is not lost during migration of a composite layout file"
7890
7891 check_file_ost_range() {
7892         local file="$1"
7893         shift
7894         local range="$*"
7895         local -a file_range
7896         local idx
7897
7898         file_range=($($LFS getstripe -y "$file" |
7899                 awk '/l_ost_idx:/ { print $NF }'))
7900
7901         if [[ "${#file_range[@]}" = 0 ]]; then
7902                 echo "No osts found for $file"
7903                 return 1
7904         fi
7905
7906         for idx in "${file_range[@]}"; do
7907                 [[ " $range " =~ " $idx " ]] ||
7908                         return 1
7909         done
7910
7911         return 0
7912 }
7913
7914 sub_test_56xg() {
7915         local stripe_opt="$1"
7916         local pool="$2"
7917         shift 2
7918         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7919
7920         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7921                 error "Fail to migrate $tfile on $pool"
7922         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7923                 error "$tfile is not in pool $pool"
7924         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7925                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7926 }
7927
7928 test_56xg() {
7929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7930         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7931         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7932                 skip "Need MDS version newer than 2.14.52"
7933
7934         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7935         local -a pool_ranges=("0 0" "1 1" "0 1")
7936
7937         # init pools
7938         for i in "${!pool_names[@]}"; do
7939                 pool_add ${pool_names[$i]} ||
7940                         error "pool_add failed (pool: ${pool_names[$i]})"
7941                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7942                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7943         done
7944
7945         # init the file to migrate
7946         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7947                 error "Unable to create $tfile on OST1"
7948         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7949                 error "Unable to write on $tfile"
7950
7951         echo "1. migrate $tfile on pool ${pool_names[0]}"
7952         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7953
7954         echo "2. migrate $tfile on pool ${pool_names[2]}"
7955         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7956
7957         echo "3. migrate $tfile on pool ${pool_names[1]}"
7958         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7959
7960         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7961         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7962         echo
7963
7964         # Clean pools
7965         destroy_test_pools ||
7966                 error "pool_destroy failed"
7967 }
7968 run_test 56xg "lfs migrate pool support"
7969
7970 test_56y() {
7971         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7972                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7973
7974         local res=""
7975         local dir=$DIR/$tdir
7976         local f1=$dir/file1
7977         local f2=$dir/file2
7978
7979         test_mkdir -p $dir || error "creating dir $dir"
7980         touch $f1 || error "creating std file $f1"
7981         $MULTIOP $f2 H2c || error "creating released file $f2"
7982
7983         # a directory can be raid0, so ask only for files
7984         res=$($LFS find $dir -L raid0 -type f | wc -l)
7985         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7986
7987         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7988         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7989
7990         # only files can be released, so no need to force file search
7991         res=$($LFS find $dir -L released)
7992         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7993
7994         res=$($LFS find $dir -type f \! -L released)
7995         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7996 }
7997 run_test 56y "lfs find -L raid0|released"
7998
7999 test_56z() { # LU-4824
8000         # This checks to make sure 'lfs find' continues after errors
8001         # There are two classes of errors that should be caught:
8002         # - If multiple paths are provided, all should be searched even if one
8003         #   errors out
8004         # - If errors are encountered during the search, it should not terminate
8005         #   early
8006         local dir=$DIR/$tdir
8007         local i
8008
8009         test_mkdir $dir
8010         for i in d{0..9}; do
8011                 test_mkdir $dir/$i
8012                 touch $dir/$i/$tfile
8013         done
8014         $LFS find $DIR/non_existent_dir $dir &&
8015                 error "$LFS find did not return an error"
8016         # Make a directory unsearchable. This should NOT be the last entry in
8017         # directory order.  Arbitrarily pick the 6th entry
8018         chmod 700 $($LFS find $dir -type d | sed '6!d')
8019
8020         $RUNAS $LFS find $DIR/non_existent $dir
8021         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8022
8023         # The user should be able to see 10 directories and 9 files
8024         (( count == 19 )) ||
8025                 error "$LFS find found $count != 19 entries after error"
8026 }
8027 run_test 56z "lfs find should continue after an error"
8028
8029 test_56aa() { # LU-5937
8030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8031
8032         local dir=$DIR/$tdir
8033
8034         mkdir $dir
8035         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8036
8037         createmany -o $dir/striped_dir/${tfile}- 1024
8038         local dirs=$($LFS find --size +8k $dir/)
8039
8040         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8041 }
8042 run_test 56aa "lfs find --size under striped dir"
8043
8044 test_56ab() { # LU-10705
8045         test_mkdir $DIR/$tdir
8046         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8047         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8048         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8049         # Flush writes to ensure valid blocks.  Need to be more thorough for
8050         # ZFS, since blocks are not allocated/returned to client immediately.
8051         sync_all_data
8052         wait_zfs_commit ost1 2
8053         cancel_lru_locks osc
8054         ls -ls $DIR/$tdir
8055
8056         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8057
8058         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8059
8060         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8061         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8062
8063         rm -f $DIR/$tdir/$tfile.[123]
8064 }
8065 run_test 56ab "lfs find --blocks"
8066
8067 # LU-11188
8068 test_56aca() {
8069         local dir="$DIR/$tdir"
8070         local perms=(001 002 003 004 005 006 007
8071                      010 020 030 040 050 060 070
8072                      100 200 300 400 500 600 700
8073                      111 222 333 444 555 666 777)
8074         local perm_minus=(8 8 4 8 4 4 2
8075                           8 8 4 8 4 4 2
8076                           8 8 4 8 4 4 2
8077                           4 4 2 4 2 2 1)
8078         local perm_slash=(8  8 12  8 12 12 14
8079                           8  8 12  8 12 12 14
8080                           8  8 12  8 12 12 14
8081                          16 16 24 16 24 24 28)
8082
8083         test_mkdir "$dir"
8084         for perm in ${perms[*]}; do
8085                 touch "$dir/$tfile.$perm"
8086                 chmod $perm "$dir/$tfile.$perm"
8087         done
8088
8089         for ((i = 0; i < ${#perms[*]}; i++)); do
8090                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8091                 (( $num == 1 )) ||
8092                         error "lfs find -perm ${perms[i]}:"\
8093                               "$num != 1"
8094
8095                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8096                 (( $num == ${perm_minus[i]} )) ||
8097                         error "lfs find -perm -${perms[i]}:"\
8098                               "$num != ${perm_minus[i]}"
8099
8100                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8101                 (( $num == ${perm_slash[i]} )) ||
8102                         error "lfs find -perm /${perms[i]}:"\
8103                               "$num != ${perm_slash[i]}"
8104         done
8105 }
8106 run_test 56aca "check lfs find -perm with octal representation"
8107
8108 test_56acb() {
8109         local dir=$DIR/$tdir
8110         # p is the permission of write and execute for user, group and other
8111         # without the umask. It is used to test +wx.
8112         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8113         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8114         local symbolic=(+t  a+t u+t g+t o+t
8115                         g+s u+s o+s +s o+sr
8116                         o=r,ug+o,u+w
8117                         u+ g+ o+ a+ ugo+
8118                         u- g- o- a- ugo-
8119                         u= g= o= a= ugo=
8120                         o=r,ug+o,u+w u=r,a+u,u+w
8121                         g=r,ugo=g,u+w u+x,+X +X
8122                         u+x,u+X u+X u+x,g+X o+r,+X
8123                         u+x,go+X +wx +rwx)
8124
8125         test_mkdir $dir
8126         for perm in ${perms[*]}; do
8127                 touch "$dir/$tfile.$perm"
8128                 chmod $perm "$dir/$tfile.$perm"
8129         done
8130
8131         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8132                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8133
8134                 (( $num == 1 )) ||
8135                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8136         done
8137 }
8138 run_test 56acb "check lfs find -perm with symbolic representation"
8139
8140 test_56acc() {
8141         local dir=$DIR/$tdir
8142         local tests="17777 787 789 abcd
8143                 ug=uu ug=a ug=gu uo=ou urw
8144                 u+xg+x a=r,u+x,"
8145
8146         test_mkdir $dir
8147         for err in $tests; do
8148                 if $LFS find $dir -perm $err 2>/dev/null; then
8149                         error "lfs find -perm $err: parsing should have failed"
8150                 fi
8151         done
8152 }
8153 run_test 56acc "check parsing error for lfs find -perm"
8154
8155 test_56ba() {
8156         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8157                 skip "Need MDS version at least 2.10.50"
8158
8159         # Create composite files with one component
8160         local dir=$DIR/$tdir
8161
8162         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8163         # Create composite files with three components
8164         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8165         # Create non-composite files
8166         createmany -o $dir/${tfile}- 10
8167
8168         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8169
8170         [[ $nfiles == 10 ]] ||
8171                 error "lfs find -E 1M found $nfiles != 10 files"
8172
8173         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8174         [[ $nfiles == 25 ]] ||
8175                 error "lfs find ! -E 1M found $nfiles != 25 files"
8176
8177         # All files have a component that starts at 0
8178         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8179         [[ $nfiles == 35 ]] ||
8180                 error "lfs find --component-start 0 - $nfiles != 35 files"
8181
8182         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8183         [[ $nfiles == 15 ]] ||
8184                 error "lfs find --component-start 2M - $nfiles != 15 files"
8185
8186         # All files created here have a componenet that does not starts at 2M
8187         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8188         [[ $nfiles == 35 ]] ||
8189                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8190
8191         # Find files with a specified number of components
8192         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8193         [[ $nfiles == 15 ]] ||
8194                 error "lfs find --component-count 3 - $nfiles != 15 files"
8195
8196         # Remember non-composite files have a component count of zero
8197         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8198         [[ $nfiles == 10 ]] ||
8199                 error "lfs find --component-count 0 - $nfiles != 10 files"
8200
8201         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8202         [[ $nfiles == 20 ]] ||
8203                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8204
8205         # All files have a flag called "init"
8206         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8207         [[ $nfiles == 35 ]] ||
8208                 error "lfs find --component-flags init - $nfiles != 35 files"
8209
8210         # Multi-component files will have a component not initialized
8211         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8212         [[ $nfiles == 15 ]] ||
8213                 error "lfs find !--component-flags init - $nfiles != 15 files"
8214
8215         rm -rf $dir
8216
8217 }
8218 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8219
8220 test_56ca() {
8221         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8222                 skip "Need MDS version at least 2.10.57"
8223
8224         local td=$DIR/$tdir
8225         local tf=$td/$tfile
8226         local dir
8227         local nfiles
8228         local cmd
8229         local i
8230         local j
8231
8232         # create mirrored directories and mirrored files
8233         mkdir $td || error "mkdir $td failed"
8234         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8235         createmany -o $tf- 10 || error "create $tf- failed"
8236
8237         for i in $(seq 2); do
8238                 dir=$td/dir$i
8239                 mkdir $dir || error "mkdir $dir failed"
8240                 $LFS mirror create -N$((3 + i)) $dir ||
8241                         error "create mirrored dir $dir failed"
8242                 createmany -o $dir/$tfile- 10 ||
8243                         error "create $dir/$tfile- failed"
8244         done
8245
8246         # change the states of some mirrored files
8247         echo foo > $tf-6
8248         for i in $(seq 2); do
8249                 dir=$td/dir$i
8250                 for j in $(seq 4 9); do
8251                         echo foo > $dir/$tfile-$j
8252                 done
8253         done
8254
8255         # find mirrored files with specific mirror count
8256         cmd="$LFS find --mirror-count 3 --type f $td"
8257         nfiles=$($cmd | wc -l)
8258         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8259
8260         cmd="$LFS find ! --mirror-count 3 --type f $td"
8261         nfiles=$($cmd | wc -l)
8262         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8263
8264         cmd="$LFS find --mirror-count +2 --type f $td"
8265         nfiles=$($cmd | wc -l)
8266         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8267
8268         cmd="$LFS find --mirror-count -6 --type f $td"
8269         nfiles=$($cmd | wc -l)
8270         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8271
8272         # find mirrored files with specific file state
8273         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8274         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8275
8276         cmd="$LFS find --mirror-state=ro --type f $td"
8277         nfiles=$($cmd | wc -l)
8278         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8279
8280         cmd="$LFS find ! --mirror-state=ro --type f $td"
8281         nfiles=$($cmd | wc -l)
8282         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8283
8284         cmd="$LFS find --mirror-state=wp --type f $td"
8285         nfiles=$($cmd | wc -l)
8286         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8287
8288         cmd="$LFS find ! --mirror-state=sp --type f $td"
8289         nfiles=$($cmd | wc -l)
8290         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8291 }
8292 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8293
8294 test_56da() { # LU-14179
8295         local path=$DIR/$tdir
8296
8297         test_mkdir $path
8298         cd $path
8299
8300         local longdir=$(str_repeat 'a' 255)
8301
8302         for i in {1..15}; do
8303                 path=$path/$longdir
8304                 test_mkdir $longdir
8305                 cd $longdir
8306         done
8307
8308         local len=${#path}
8309         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8310
8311         test_mkdir $lastdir
8312         cd $lastdir
8313         # PATH_MAX-1
8314         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8315
8316         # NAME_MAX
8317         touch $(str_repeat 'f' 255)
8318
8319         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8320                 error "lfs find reported an error"
8321
8322         rm -rf $DIR/$tdir
8323 }
8324 run_test 56da "test lfs find with long paths"
8325
8326 test_56ea() { #LU-10378
8327         local path=$DIR/$tdir
8328         local pool=$TESTNAME
8329
8330         # Create ost pool
8331         pool_add $pool || error "pool_add $pool failed"
8332         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8333                 error "adding targets to $pool failed"
8334
8335         # Set default pool on directory before creating file
8336         mkdir $path || error "mkdir $path failed"
8337         $LFS setstripe -p $pool $path ||
8338                 error "set OST pool on $pool failed"
8339         touch $path/$tfile || error "touch $path/$tfile failed"
8340
8341         # Compare basic file attributes from -printf and stat
8342         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8343         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8344
8345         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8346                 error "Attrs from lfs find and stat don't match"
8347
8348         # Compare Lustre attributes from lfs find and lfs getstripe
8349         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8350         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8351         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8352         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8353         local fpool=$($LFS getstripe --pool $path/$tfile)
8354         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8355
8356         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8357                 error "Attrs from lfs find and lfs getstripe don't match"
8358
8359         # Verify behavior for unknown escape/format sequences
8360         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8361
8362         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8363                 error "Escape/format codes don't match"
8364 }
8365 run_test 56ea "test lfs find -printf option"
8366
8367 test_57a() {
8368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8369         # note test will not do anything if MDS is not local
8370         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8371                 skip_env "ldiskfs only test"
8372         fi
8373         remote_mds_nodsh && skip "remote MDS with nodsh"
8374
8375         local MNTDEV="osd*.*MDT*.mntdev"
8376         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8377         [ -z "$DEV" ] && error "can't access $MNTDEV"
8378         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8379                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8380                         error "can't access $DEV"
8381                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8382                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8383                 rm $TMP/t57a.dump
8384         done
8385 }
8386 run_test 57a "verify MDS filesystem created with large inodes =="
8387
8388 test_57b() {
8389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8390         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8391                 skip_env "ldiskfs only test"
8392         fi
8393         remote_mds_nodsh && skip "remote MDS with nodsh"
8394
8395         local dir=$DIR/$tdir
8396         local filecount=100
8397         local file1=$dir/f1
8398         local fileN=$dir/f$filecount
8399
8400         rm -rf $dir || error "removing $dir"
8401         test_mkdir -c1 $dir
8402         local mdtidx=$($LFS getstripe -m $dir)
8403         local mdtname=MDT$(printf %04x $mdtidx)
8404         local facet=mds$((mdtidx + 1))
8405
8406         echo "mcreating $filecount files"
8407         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8408
8409         # verify that files do not have EAs yet
8410         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8411                 error "$file1 has an EA"
8412         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8413                 error "$fileN has an EA"
8414
8415         sync
8416         sleep 1
8417         df $dir  #make sure we get new statfs data
8418         local mdsfree=$(do_facet $facet \
8419                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8420         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8421         local file
8422
8423         echo "opening files to create objects/EAs"
8424         for file in $(seq -f $dir/f%g 1 $filecount); do
8425                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8426                         error "opening $file"
8427         done
8428
8429         # verify that files have EAs now
8430         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8431         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8432
8433         sleep 1  #make sure we get new statfs data
8434         df $dir
8435         local mdsfree2=$(do_facet $facet \
8436                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8437         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8438
8439         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8440                 if [ "$mdsfree" != "$mdsfree2" ]; then
8441                         error "MDC before $mdcfree != after $mdcfree2"
8442                 else
8443                         echo "MDC before $mdcfree != after $mdcfree2"
8444                         echo "unable to confirm if MDS has large inodes"
8445                 fi
8446         fi
8447         rm -rf $dir
8448 }
8449 run_test 57b "default LOV EAs are stored inside large inodes ==="
8450
8451 test_58() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453         [ -z "$(which wiretest 2>/dev/null)" ] &&
8454                         skip_env "could not find wiretest"
8455
8456         wiretest
8457 }
8458 run_test 58 "verify cross-platform wire constants =============="
8459
8460 test_59() {
8461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8462
8463         echo "touch 130 files"
8464         createmany -o $DIR/f59- 130
8465         echo "rm 130 files"
8466         unlinkmany $DIR/f59- 130
8467         sync
8468         # wait for commitment of removal
8469         wait_delete_completed
8470 }
8471 run_test 59 "verify cancellation of llog records async ========="
8472
8473 TEST60_HEAD="test_60 run $RANDOM"
8474 test_60a() {
8475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8476         remote_mgs_nodsh && skip "remote MGS with nodsh"
8477         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8478                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8479                         skip_env "missing subtest run-llog.sh"
8480
8481         log "$TEST60_HEAD - from kernel mode"
8482         do_facet mgs "$LCTL dk > /dev/null"
8483         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8484         do_facet mgs $LCTL dk > $TMP/$tfile
8485
8486         # LU-6388: test llog_reader
8487         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8488         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8489         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8490                         skip_env "missing llog_reader"
8491         local fstype=$(facet_fstype mgs)
8492         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8493                 skip_env "Only for ldiskfs or zfs type mgs"
8494
8495         local mntpt=$(facet_mntpt mgs)
8496         local mgsdev=$(mgsdevname 1)
8497         local fid_list
8498         local fid
8499         local rec_list
8500         local rec
8501         local rec_type
8502         local obj_file
8503         local path
8504         local seq
8505         local oid
8506         local pass=true
8507
8508         #get fid and record list
8509         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8510                 tail -n 4))
8511         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8512                 tail -n 4))
8513         #remount mgs as ldiskfs or zfs type
8514         stop mgs || error "stop mgs failed"
8515         mount_fstype mgs || error "remount mgs failed"
8516         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8517                 fid=${fid_list[i]}
8518                 rec=${rec_list[i]}
8519                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8520                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8521                 oid=$((16#$oid))
8522
8523                 case $fstype in
8524                         ldiskfs )
8525                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8526                         zfs )
8527                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8528                 esac
8529                 echo "obj_file is $obj_file"
8530                 do_facet mgs $llog_reader $obj_file
8531
8532                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8533                         awk '{ print $3 }' | sed -e "s/^type=//g")
8534                 if [ $rec_type != $rec ]; then
8535                         echo "FAILED test_60a wrong record type $rec_type," \
8536                               "should be $rec"
8537                         pass=false
8538                         break
8539                 fi
8540
8541                 #check obj path if record type is LLOG_LOGID_MAGIC
8542                 if [ "$rec" == "1064553b" ]; then
8543                         path=$(do_facet mgs $llog_reader $obj_file |
8544                                 grep "path=" | awk '{ print $NF }' |
8545                                 sed -e "s/^path=//g")
8546                         if [ $obj_file != $mntpt/$path ]; then
8547                                 echo "FAILED test_60a wrong obj path" \
8548                                       "$montpt/$path, should be $obj_file"
8549                                 pass=false
8550                                 break
8551                         fi
8552                 fi
8553         done
8554         rm -f $TMP/$tfile
8555         #restart mgs before "error", otherwise it will block the next test
8556         stop mgs || error "stop mgs failed"
8557         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8558         $pass || error "test failed, see FAILED test_60a messages for specifics"
8559 }
8560 run_test 60a "llog_test run from kernel module and test llog_reader"
8561
8562 test_60b() { # bug 6411
8563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8564
8565         dmesg > $DIR/$tfile
8566         LLOG_COUNT=$(do_facet mgs dmesg |
8567                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8568                           /llog_[a-z]*.c:[0-9]/ {
8569                                 if (marker)
8570                                         from_marker++
8571                                 from_begin++
8572                           }
8573                           END {
8574                                 if (marker)
8575                                         print from_marker
8576                                 else
8577                                         print from_begin
8578                           }")
8579
8580         [[ $LLOG_COUNT -gt 120 ]] &&
8581                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8582 }
8583 run_test 60b "limit repeated messages from CERROR/CWARN"
8584
8585 test_60c() {
8586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8587
8588         echo "create 5000 files"
8589         createmany -o $DIR/f60c- 5000
8590 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8591         lctl set_param fail_loc=0x80000137
8592         unlinkmany $DIR/f60c- 5000
8593         lctl set_param fail_loc=0
8594 }
8595 run_test 60c "unlink file when mds full"
8596
8597 test_60d() {
8598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8599
8600         SAVEPRINTK=$(lctl get_param -n printk)
8601         # verify "lctl mark" is even working"
8602         MESSAGE="test message ID $RANDOM $$"
8603         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8604         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8605
8606         lctl set_param printk=0 || error "set lnet.printk failed"
8607         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8608         MESSAGE="new test message ID $RANDOM $$"
8609         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8610         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8611         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8612
8613         lctl set_param -n printk="$SAVEPRINTK"
8614 }
8615 run_test 60d "test printk console message masking"
8616
8617 test_60e() {
8618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8619         remote_mds_nodsh && skip "remote MDS with nodsh"
8620
8621         touch $DIR/$tfile
8622 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8623         do_facet mds1 lctl set_param fail_loc=0x15b
8624         rm $DIR/$tfile
8625 }
8626 run_test 60e "no space while new llog is being created"
8627
8628 test_60f() {
8629         local old_path=$($LCTL get_param -n debug_path)
8630
8631         stack_trap "$LCTL set_param debug_path=$old_path"
8632         stack_trap "rm -f $TMP/$tfile*"
8633         rm -f $TMP/$tfile* 2> /dev/null
8634         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8635         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8636         test_mkdir $DIR/$tdir
8637         # retry in case the open is cached and not released
8638         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8639                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8640                 sleep 0.1
8641         done
8642         ls $TMP/$tfile*
8643         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8644 }
8645 run_test 60f "change debug_path works"
8646
8647 test_60g() {
8648         local pid
8649         local i
8650
8651         test_mkdir -c $MDSCOUNT $DIR/$tdir
8652
8653         (
8654                 local index=0
8655                 while true; do
8656                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8657                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8658                                 2>/dev/null
8659                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8660                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8661                         index=$((index + 1))
8662                 done
8663         ) &
8664
8665         pid=$!
8666
8667         for i in {0..100}; do
8668                 # define OBD_FAIL_OSD_TXN_START    0x19a
8669                 local index=$((i % MDSCOUNT + 1))
8670
8671                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8672                         > /dev/null
8673                 sleep 0.01
8674         done
8675
8676         kill -9 $pid
8677
8678         for i in $(seq $MDSCOUNT); do
8679                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8680         done
8681
8682         mkdir $DIR/$tdir/new || error "mkdir failed"
8683         rmdir $DIR/$tdir/new || error "rmdir failed"
8684
8685         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8686                 -t namespace
8687         for i in $(seq $MDSCOUNT); do
8688                 wait_update_facet mds$i "$LCTL get_param -n \
8689                         mdd.$(facet_svc mds$i).lfsck_namespace |
8690                         awk '/^status/ { print \\\$2 }'" "completed"
8691         done
8692
8693         ls -R $DIR/$tdir
8694         rm -rf $DIR/$tdir || error "rmdir failed"
8695 }
8696 run_test 60g "transaction abort won't cause MDT hung"
8697
8698 test_60h() {
8699         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8700                 skip "Need MDS version at least 2.12.52"
8701         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8702
8703         local f
8704
8705         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8706         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8707         for fail_loc in 0x80000188 0x80000189; do
8708                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8709                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8710                         error "mkdir $dir-$fail_loc failed"
8711                 for i in {0..10}; do
8712                         # create may fail on missing stripe
8713                         echo $i > $DIR/$tdir-$fail_loc/$i
8714                 done
8715                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8716                         error "getdirstripe $tdir-$fail_loc failed"
8717                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8718                         error "migrate $tdir-$fail_loc failed"
8719                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8720                         error "getdirstripe $tdir-$fail_loc failed"
8721                 pushd $DIR/$tdir-$fail_loc
8722                 for f in *; do
8723                         echo $f | cmp $f - || error "$f data mismatch"
8724                 done
8725                 popd
8726                 rm -rf $DIR/$tdir-$fail_loc
8727         done
8728 }
8729 run_test 60h "striped directory with missing stripes can be accessed"
8730
8731 function t60i_load() {
8732         mkdir $DIR/$tdir
8733         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8734         $LCTL set_param fail_loc=0x131c fail_val=1
8735         for ((i=0; i<5000; i++)); do
8736                 touch $DIR/$tdir/f$i
8737         done
8738 }
8739
8740 test_60i() {
8741         changelog_register || error "changelog_register failed"
8742         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8743         changelog_users $SINGLEMDS | grep -q $cl_user ||
8744                 error "User $cl_user not found in changelog_users"
8745         changelog_chmask "ALL"
8746         t60i_load &
8747         local PID=$!
8748         for((i=0; i<100; i++)); do
8749                 changelog_dump >/dev/null ||
8750                         error "can't read changelog"
8751         done
8752         kill $PID
8753         wait $PID
8754         changelog_deregister || error "changelog_deregister failed"
8755         $LCTL set_param fail_loc=0
8756 }
8757 run_test 60i "llog: new record vs reader race"
8758
8759 test_61a() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761
8762         f="$DIR/f61"
8763         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8764         cancel_lru_locks osc
8765         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8766         sync
8767 }
8768 run_test 61a "mmap() writes don't make sync hang ================"
8769
8770 test_61b() {
8771         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8772 }
8773 run_test 61b "mmap() of unstriped file is successful"
8774
8775 # bug 2330 - insufficient obd_match error checking causes LBUG
8776 test_62() {
8777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8778
8779         f="$DIR/f62"
8780         echo foo > $f
8781         cancel_lru_locks osc
8782         lctl set_param fail_loc=0x405
8783         cat $f && error "cat succeeded, expect -EIO"
8784         lctl set_param fail_loc=0
8785 }
8786 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8787 # match every page all of the time.
8788 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8789
8790 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8791 # Though this test is irrelevant anymore, it helped to reveal some
8792 # other grant bugs (LU-4482), let's keep it.
8793 test_63a() {   # was test_63
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795
8796         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8797
8798         for i in `seq 10` ; do
8799                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8800                 sleep 5
8801                 kill $!
8802                 sleep 1
8803         done
8804
8805         rm -f $DIR/f63 || true
8806 }
8807 run_test 63a "Verify oig_wait interruption does not crash ======="
8808
8809 # bug 2248 - async write errors didn't return to application on sync
8810 # bug 3677 - async write errors left page locked
8811 test_63b() {
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813
8814         debugsave
8815         lctl set_param debug=-1
8816
8817         # ensure we have a grant to do async writes
8818         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8819         rm $DIR/$tfile
8820
8821         sync    # sync lest earlier test intercept the fail_loc
8822
8823         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8824         lctl set_param fail_loc=0x80000406
8825         $MULTIOP $DIR/$tfile Owy && \
8826                 error "sync didn't return ENOMEM"
8827         sync; sleep 2; sync     # do a real sync this time to flush page
8828         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8829                 error "locked page left in cache after async error" || true
8830         debugrestore
8831 }
8832 run_test 63b "async write errors should be returned to fsync ==="
8833
8834 test_64a () {
8835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8836
8837         lfs df $DIR
8838         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8839 }
8840 run_test 64a "verify filter grant calculations (in kernel) ====="
8841
8842 test_64b () {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844
8845         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8846 }
8847 run_test 64b "check out-of-space detection on client"
8848
8849 test_64c() {
8850         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8851 }
8852 run_test 64c "verify grant shrink"
8853
8854 import_param() {
8855         local tgt=$1
8856         local param=$2
8857
8858         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8859 }
8860
8861 # this does exactly what osc_request.c:osc_announce_cached() does in
8862 # order to calculate max amount of grants to ask from server
8863 want_grant() {
8864         local tgt=$1
8865
8866         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8867         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8868
8869         ((rpc_in_flight++));
8870         nrpages=$((nrpages * rpc_in_flight))
8871
8872         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8873
8874         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8875
8876         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8877         local undirty=$((nrpages * PAGE_SIZE))
8878
8879         local max_extent_pages
8880         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8881         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8882         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8883         local grant_extent_tax
8884         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8885
8886         undirty=$((undirty + nrextents * grant_extent_tax))
8887
8888         echo $undirty
8889 }
8890
8891 # this is size of unit for grant allocation. It should be equal to
8892 # what tgt_grant.c:tgt_grant_chunk() calculates
8893 grant_chunk() {
8894         local tgt=$1
8895         local max_brw_size
8896         local grant_extent_tax
8897
8898         max_brw_size=$(import_param $tgt max_brw_size)
8899
8900         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8901
8902         echo $(((max_brw_size + grant_extent_tax) * 2))
8903 }
8904
8905 test_64d() {
8906         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8907                 skip "OST < 2.10.55 doesn't limit grants enough"
8908
8909         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8910
8911         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8912                 skip "no grant_param connect flag"
8913
8914         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8915
8916         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8917         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8918
8919
8920         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8921         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8922
8923         $LFS setstripe $DIR/$tfile -i 0 -c 1
8924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8925         ddpid=$!
8926
8927         while kill -0 $ddpid; do
8928                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8929
8930                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8931                         kill $ddpid
8932                         error "cur_grant $cur_grant > $max_cur_granted"
8933                 fi
8934
8935                 sleep 1
8936         done
8937 }
8938 run_test 64d "check grant limit exceed"
8939
8940 check_grants() {
8941         local tgt=$1
8942         local expected=$2
8943         local msg=$3
8944         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8945
8946         ((cur_grants == expected)) ||
8947                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8948 }
8949
8950 round_up_p2() {
8951         echo $((($1 + $2 - 1) & ~($2 - 1)))
8952 }
8953
8954 test_64e() {
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8957                 skip "Need OSS version at least 2.11.56"
8958
8959         # Remount client to reset grant
8960         remount_client $MOUNT || error "failed to remount client"
8961         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8962
8963         local init_grants=$(import_param $osc_tgt initial_grant)
8964
8965         check_grants $osc_tgt $init_grants "init grants"
8966
8967         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8968         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8969         local gbs=$(import_param $osc_tgt grant_block_size)
8970
8971         # write random number of bytes from max_brw_size / 4 to max_brw_size
8972         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8973         # align for direct io
8974         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8975         # round to grant consumption unit
8976         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8977
8978         local grants=$((wb_round_up + extent_tax))
8979
8980         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8981
8982         # define OBD_FAIL_TGT_NO_GRANT 0x725
8983         # make the server not grant more back
8984         do_facet ost1 $LCTL set_param fail_loc=0x725
8985         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8986
8987         do_facet ost1 $LCTL set_param fail_loc=0
8988
8989         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8990
8991         rm -f $DIR/$tfile || error "rm failed"
8992
8993         # Remount client to reset grant
8994         remount_client $MOUNT || error "failed to remount client"
8995         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8996
8997         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8998
8999         # define OBD_FAIL_TGT_NO_GRANT 0x725
9000         # make the server not grant more back
9001         do_facet ost1 $LCTL set_param fail_loc=0x725
9002         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9003         do_facet ost1 $LCTL set_param fail_loc=0
9004
9005         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9006 }
9007 run_test 64e "check grant consumption (no grant allocation)"
9008
9009 test_64f() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         # Remount client to reset grant
9013         remount_client $MOUNT || error "failed to remount client"
9014         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9015
9016         local init_grants=$(import_param $osc_tgt initial_grant)
9017         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9018         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9019         local gbs=$(import_param $osc_tgt grant_block_size)
9020         local chunk=$(grant_chunk $osc_tgt)
9021
9022         # write random number of bytes from max_brw_size / 4 to max_brw_size
9023         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9024         # align for direct io
9025         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9026         # round to grant consumption unit
9027         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9028
9029         local grants=$((wb_round_up + extent_tax))
9030
9031         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9032         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9033                 error "error writing to $DIR/$tfile"
9034
9035         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9036                 "direct io with grant allocation"
9037
9038         rm -f $DIR/$tfile || error "rm failed"
9039
9040         # Remount client to reset grant
9041         remount_client $MOUNT || error "failed to remount client"
9042         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9043
9044         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9045
9046         local cmd="oO_WRONLY:w${write_bytes}_yc"
9047
9048         $MULTIOP $DIR/$tfile $cmd &
9049         MULTIPID=$!
9050         sleep 1
9051
9052         check_grants $osc_tgt $((init_grants - grants)) \
9053                 "buffered io, not write rpc"
9054
9055         kill -USR1 $MULTIPID
9056         wait
9057
9058         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9059                 "buffered io, one RPC"
9060 }
9061 run_test 64f "check grant consumption (with grant allocation)"
9062
9063 test_64g() {
9064         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9065                 skip "Need MDS version at least 2.14.56"
9066
9067         local mdts=$(comma_list $(mdts_nodes))
9068
9069         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9070                         tr '\n' ' ')
9071         stack_trap "$LCTL set_param $old"
9072
9073         # generate dirty pages and increase dirty granted on MDT
9074         stack_trap "rm -f $DIR/$tfile-*"
9075         for (( i = 0; i < 10; i++)); do
9076                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9077                         error "can't set stripe"
9078                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9079                         error "can't dd"
9080                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9081                         $LFS getstripe $DIR/$tfile-$i
9082                         error "not DoM file"
9083                 }
9084         done
9085
9086         # flush dirty pages
9087         sync
9088
9089         # wait until grant shrink reset grant dirty on MDTs
9090         for ((i = 0; i < 120; i++)); do
9091                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9092                         awk '{sum=sum+$1} END {print sum}')
9093                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9094                 echo "$grant_dirty grants, $vm_dirty pages"
9095                 (( grant_dirty + vm_dirty == 0 )) && break
9096                 (( i == 3 )) && sync &&
9097                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9098                 sleep 1
9099         done
9100
9101         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9102                 awk '{sum=sum+$1} END {print sum}')
9103         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9104 }
9105 run_test 64g "grant shrink on MDT"
9106
9107 test_64h() {
9108         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9109                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9110
9111         local instance=$($LFS getname -i $DIR)
9112         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9113         local num_exps=$(do_facet ost1 \
9114             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9115         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9116         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9117         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9118
9119         # 10MiB is for file to be written, max_brw_size * 16 *
9120         # num_exps is space reserve so that tgt_grant_shrink() decided
9121         # to not shrink
9122         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9123         (( avail * 1024 < expect )) &&
9124                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9125
9126         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9127         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9128         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9129         $LCTL set_param osc.*OST0000*.grant_shrink=1
9130         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9131
9132         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9134
9135         # drop cache so that coming read would do rpc
9136         cancel_lru_locks osc
9137
9138         # shrink interval is set to 10, pause for 7 seconds so that
9139         # grant thread did not wake up yet but coming read entered
9140         # shrink mode for rpc (osc_should_shrink_grant())
9141         sleep 7
9142
9143         declare -a cur_grant_bytes
9144         declare -a tot_granted
9145         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9146         tot_granted[0]=$(do_facet ost1 \
9147             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9148
9149         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9150
9151         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9152         tot_granted[1]=$(do_facet ost1 \
9153             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9154
9155         # grant change should be equal on both sides
9156         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9157                 tot_granted[0] - tot_granted[1])) ||
9158                 error "grant change mismatch, "                                \
9159                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9160                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9161 }
9162 run_test 64h "grant shrink on read"
9163
9164 test_64i() {
9165         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9166                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9167
9168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9169         remote_ost_nodsh && skip "remote OSTs with nodsh"
9170
9171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9172
9173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9174
9175         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9176         local instance=$($LFS getname -i $DIR)
9177
9178         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9179         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9180
9181         # shrink grants and simulate rpc loss
9182         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9183         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9184         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9185
9186         fail ost1
9187
9188         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9189
9190         local testid=$(echo $TESTNAME | tr '_' ' ')
9191
9192         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9193                 grep "GRANT, real grant" &&
9194                 error "client has more grants then it owns" || true
9195 }
9196 run_test 64i "shrink on reconnect"
9197
9198 # bug 1414 - set/get directories' stripe info
9199 test_65a() {
9200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9201
9202         test_mkdir $DIR/$tdir
9203         touch $DIR/$tdir/f1
9204         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9205 }
9206 run_test 65a "directory with no stripe info"
9207
9208 test_65b() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210
9211         test_mkdir $DIR/$tdir
9212         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9213
9214         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9215                                                 error "setstripe"
9216         touch $DIR/$tdir/f2
9217         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9218 }
9219 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9220
9221 test_65c() {
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9224
9225         test_mkdir $DIR/$tdir
9226         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9227
9228         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9229                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9230         touch $DIR/$tdir/f3
9231         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9232 }
9233 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9234
9235 test_65d() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         test_mkdir $DIR/$tdir
9239         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9240         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9241
9242         if [[ $STRIPECOUNT -le 0 ]]; then
9243                 sc=1
9244         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9245                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9246                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9247         else
9248                 sc=$(($STRIPECOUNT - 1))
9249         fi
9250         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9251         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9252         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9253                 error "lverify failed"
9254 }
9255 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9256
9257 test_65e() {
9258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9259
9260         test_mkdir $DIR/$tdir
9261
9262         $LFS setstripe $DIR/$tdir || error "setstripe"
9263         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9264                                         error "no stripe info failed"
9265         touch $DIR/$tdir/f6
9266         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9267 }
9268 run_test 65e "directory setstripe defaults"
9269
9270 test_65f() {
9271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9272
9273         test_mkdir $DIR/${tdir}f
9274         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9275                 error "setstripe succeeded" || true
9276 }
9277 run_test 65f "dir setstripe permission (should return error) ==="
9278
9279 test_65g() {
9280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9281
9282         test_mkdir $DIR/$tdir
9283         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9284
9285         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9286                 error "setstripe -S failed"
9287         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9288         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9289                 error "delete default stripe failed"
9290 }
9291 run_test 65g "directory setstripe -d"
9292
9293 test_65h() {
9294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9295
9296         test_mkdir $DIR/$tdir
9297         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9298
9299         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9300                 error "setstripe -S failed"
9301         test_mkdir $DIR/$tdir/dd1
9302         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9303                 error "stripe info inherit failed"
9304 }
9305 run_test 65h "directory stripe info inherit ===================="
9306
9307 test_65i() {
9308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9309
9310         save_layout_restore_at_exit $MOUNT
9311
9312         # bug6367: set non-default striping on root directory
9313         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9314
9315         # bug12836: getstripe on -1 default directory striping
9316         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9317
9318         # bug12836: getstripe -v on -1 default directory striping
9319         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9320
9321         # bug12836: new find on -1 default directory striping
9322         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9323 }
9324 run_test 65i "various tests to set root directory striping"
9325
9326 test_65j() { # bug6367
9327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9328
9329         sync; sleep 1
9330
9331         # if we aren't already remounting for each test, do so for this test
9332         if [ "$I_MOUNTED" = "yes" ]; then
9333                 cleanup || error "failed to unmount"
9334                 setup
9335         fi
9336
9337         save_layout_restore_at_exit $MOUNT
9338
9339         $LFS setstripe -d $MOUNT || error "setstripe failed"
9340 }
9341 run_test 65j "set default striping on root directory (bug 6367)="
9342
9343 cleanup_65k() {
9344         rm -rf $DIR/$tdir
9345         wait_delete_completed
9346         do_facet $SINGLEMDS "lctl set_param -n \
9347                 osp.$ost*MDT0000.max_create_count=$max_count"
9348         do_facet $SINGLEMDS "lctl set_param -n \
9349                 osp.$ost*MDT0000.create_count=$count"
9350         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9351         echo $INACTIVE_OSC "is Activate"
9352
9353         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9354 }
9355
9356 test_65k() { # bug11679
9357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9359         remote_mds_nodsh && skip "remote MDS with nodsh"
9360
9361         local disable_precreate=true
9362         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9363                 disable_precreate=false
9364
9365         echo "Check OST status: "
9366         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9367                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9368
9369         for OSC in $MDS_OSCS; do
9370                 echo $OSC "is active"
9371                 do_facet $SINGLEMDS lctl --device %$OSC activate
9372         done
9373
9374         for INACTIVE_OSC in $MDS_OSCS; do
9375                 local ost=$(osc_to_ost $INACTIVE_OSC)
9376                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9377                                lov.*md*.target_obd |
9378                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9379
9380                 mkdir -p $DIR/$tdir
9381                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9382                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9383
9384                 echo "Deactivate: " $INACTIVE_OSC
9385                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9386
9387                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9388                               osp.$ost*MDT0000.create_count")
9389                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9390                                   osp.$ost*MDT0000.max_create_count")
9391                 $disable_precreate &&
9392                         do_facet $SINGLEMDS "lctl set_param -n \
9393                                 osp.$ost*MDT0000.max_create_count=0"
9394
9395                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9396                         [ -f $DIR/$tdir/$idx ] && continue
9397                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9398                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9399                                 { cleanup_65k;
9400                                   error "setstripe $idx should succeed"; }
9401                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9402                 done
9403                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9404                 rmdir $DIR/$tdir
9405
9406                 do_facet $SINGLEMDS "lctl set_param -n \
9407                         osp.$ost*MDT0000.max_create_count=$max_count"
9408                 do_facet $SINGLEMDS "lctl set_param -n \
9409                         osp.$ost*MDT0000.create_count=$count"
9410                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9411                 echo $INACTIVE_OSC "is Activate"
9412
9413                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9414         done
9415 }
9416 run_test 65k "validate manual striping works properly with deactivated OSCs"
9417
9418 test_65l() { # bug 12836
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420
9421         test_mkdir -p $DIR/$tdir/test_dir
9422         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9423         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9424 }
9425 run_test 65l "lfs find on -1 stripe dir ========================"
9426
9427 test_65m() {
9428         local layout=$(save_layout $MOUNT)
9429         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9430                 restore_layout $MOUNT $layout
9431                 error "setstripe should fail by non-root users"
9432         }
9433         true
9434 }
9435 run_test 65m "normal user can't set filesystem default stripe"
9436
9437 test_65n() {
9438         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9439         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9440                 skip "Need MDS version at least 2.12.50"
9441         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9442
9443         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9444         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9445         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9446
9447         save_layout_restore_at_exit $MOUNT
9448
9449         # new subdirectory under root directory should not inherit
9450         # the default layout from root
9451         local dir1=$MOUNT/$tdir-1
9452         mkdir $dir1 || error "mkdir $dir1 failed"
9453         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9454                 error "$dir1 shouldn't have LOV EA"
9455
9456         # delete the default layout on root directory
9457         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9458
9459         local dir2=$MOUNT/$tdir-2
9460         mkdir $dir2 || error "mkdir $dir2 failed"
9461         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9462                 error "$dir2 shouldn't have LOV EA"
9463
9464         # set a new striping pattern on root directory
9465         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9466         local new_def_stripe_size=$((def_stripe_size * 2))
9467         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9468                 error "set stripe size on $MOUNT failed"
9469
9470         # new file created in $dir2 should inherit the new stripe size from
9471         # the filesystem default
9472         local file2=$dir2/$tfile-2
9473         touch $file2 || error "touch $file2 failed"
9474
9475         local file2_stripe_size=$($LFS getstripe -S $file2)
9476         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9477         {
9478                 echo "file2_stripe_size: '$file2_stripe_size'"
9479                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9480                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9481         }
9482
9483         local dir3=$MOUNT/$tdir-3
9484         mkdir $dir3 || error "mkdir $dir3 failed"
9485         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9486         # the root layout, which is the actual default layout that will be used
9487         # when new files are created in $dir3.
9488         local dir3_layout=$(get_layout_param $dir3)
9489         local root_dir_layout=$(get_layout_param $MOUNT)
9490         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9491         {
9492                 echo "dir3_layout: '$dir3_layout'"
9493                 echo "root_dir_layout: '$root_dir_layout'"
9494                 error "$dir3 should show the default layout from $MOUNT"
9495         }
9496
9497         # set OST pool on root directory
9498         local pool=$TESTNAME
9499         pool_add $pool || error "add $pool failed"
9500         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9501                 error "add targets to $pool failed"
9502
9503         $LFS setstripe -p $pool $MOUNT ||
9504                 error "set OST pool on $MOUNT failed"
9505
9506         # new file created in $dir3 should inherit the pool from
9507         # the filesystem default
9508         local file3=$dir3/$tfile-3
9509         touch $file3 || error "touch $file3 failed"
9510
9511         local file3_pool=$($LFS getstripe -p $file3)
9512         [[ "$file3_pool" = "$pool" ]] ||
9513                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9514
9515         local dir4=$MOUNT/$tdir-4
9516         mkdir $dir4 || error "mkdir $dir4 failed"
9517         local dir4_layout=$(get_layout_param $dir4)
9518         root_dir_layout=$(get_layout_param $MOUNT)
9519         echo "$LFS getstripe -d $dir4"
9520         $LFS getstripe -d $dir4
9521         echo "$LFS getstripe -d $MOUNT"
9522         $LFS getstripe -d $MOUNT
9523         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9524         {
9525                 echo "dir4_layout: '$dir4_layout'"
9526                 echo "root_dir_layout: '$root_dir_layout'"
9527                 error "$dir4 should show the default layout from $MOUNT"
9528         }
9529
9530         # new file created in $dir4 should inherit the pool from
9531         # the filesystem default
9532         local file4=$dir4/$tfile-4
9533         touch $file4 || error "touch $file4 failed"
9534
9535         local file4_pool=$($LFS getstripe -p $file4)
9536         [[ "$file4_pool" = "$pool" ]] ||
9537                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9538
9539         # new subdirectory under non-root directory should inherit
9540         # the default layout from its parent directory
9541         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9542                 error "set directory layout on $dir4 failed"
9543
9544         local dir5=$dir4/$tdir-5
9545         mkdir $dir5 || error "mkdir $dir5 failed"
9546
9547         dir4_layout=$(get_layout_param $dir4)
9548         local dir5_layout=$(get_layout_param $dir5)
9549         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9550         {
9551                 echo "dir4_layout: '$dir4_layout'"
9552                 echo "dir5_layout: '$dir5_layout'"
9553                 error "$dir5 should inherit the default layout from $dir4"
9554         }
9555
9556         # though subdir under ROOT doesn't inherit default layout, but
9557         # its sub dir/file should be created with default layout.
9558         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9559         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9560                 skip "Need MDS version at least 2.12.59"
9561
9562         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9563         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9564         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9565
9566         if [ $default_lmv_hash == "none" ]; then
9567                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9568         else
9569                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9570                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9571         fi
9572
9573         $LFS setdirstripe -D -c 2 $MOUNT ||
9574                 error "setdirstripe -D -c 2 failed"
9575         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9576         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9577         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9578
9579         # $dir4 layout includes pool
9580         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9581         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9582                 error "pool lost on setstripe"
9583         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9584         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9585                 error "pool lost on compound layout setstripe"
9586 }
9587 run_test 65n "don't inherit default layout from root for new subdirectories"
9588
9589 # bug 2543 - update blocks count on client
9590 test_66() {
9591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9592
9593         COUNT=${COUNT:-8}
9594         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9595         sync; sync_all_data; sync; sync_all_data
9596         cancel_lru_locks osc
9597         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9598         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9599 }
9600 run_test 66 "update inode blocks count on client ==============="
9601
9602 meminfo() {
9603         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9604 }
9605
9606 swap_used() {
9607         swapon -s | awk '($1 == "'$1'") { print $4 }'
9608 }
9609
9610 # bug5265, obdfilter oa2dentry return -ENOENT
9611 # #define OBD_FAIL_SRV_ENOENT 0x217
9612 test_69() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614         remote_ost_nodsh && skip "remote OST with nodsh"
9615
9616         f="$DIR/$tfile"
9617         $LFS setstripe -c 1 -i 0 $f
9618
9619         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9620
9621         do_facet ost1 lctl set_param fail_loc=0x217
9622         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9623         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9624
9625         do_facet ost1 lctl set_param fail_loc=0
9626         $DIRECTIO write $f 0 2 || error "write error"
9627
9628         cancel_lru_locks osc
9629         $DIRECTIO read $f 0 1 || error "read error"
9630
9631         do_facet ost1 lctl set_param fail_loc=0x217
9632         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9633
9634         do_facet ost1 lctl set_param fail_loc=0
9635         rm -f $f
9636 }
9637 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9638
9639 test_71() {
9640         test_mkdir $DIR/$tdir
9641         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9642         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9643 }
9644 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9645
9646 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9648         [ "$RUNAS_ID" = "$UID" ] &&
9649                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9650         # Check that testing environment is properly set up. Skip if not
9651         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9652                 skip_env "User $RUNAS_ID does not exist - skipping"
9653
9654         touch $DIR/$tfile
9655         chmod 777 $DIR/$tfile
9656         chmod ug+s $DIR/$tfile
9657         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9658                 error "$RUNAS dd $DIR/$tfile failed"
9659         # See if we are still setuid/sgid
9660         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9661                 error "S/gid is not dropped on write"
9662         # Now test that MDS is updated too
9663         cancel_lru_locks mdc
9664         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9665                 error "S/gid is not dropped on MDS"
9666         rm -f $DIR/$tfile
9667 }
9668 run_test 72a "Test that remove suid works properly (bug5695) ===="
9669
9670 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9671         local perm
9672
9673         [ "$RUNAS_ID" = "$UID" ] &&
9674                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9675         [ "$RUNAS_ID" -eq 0 ] &&
9676                 skip_env "RUNAS_ID = 0 -- skipping"
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         # Check that testing environment is properly set up. Skip if not
9679         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9680                 skip_env "User $RUNAS_ID does not exist - skipping"
9681
9682         touch $DIR/${tfile}-f{g,u}
9683         test_mkdir $DIR/${tfile}-dg
9684         test_mkdir $DIR/${tfile}-du
9685         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9686         chmod g+s $DIR/${tfile}-{f,d}g
9687         chmod u+s $DIR/${tfile}-{f,d}u
9688         for perm in 777 2777 4777; do
9689                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9690                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9691                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9692                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9693         done
9694         true
9695 }
9696 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9697
9698 # bug 3462 - multiple simultaneous MDC requests
9699 test_73() {
9700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9701
9702         test_mkdir $DIR/d73-1
9703         test_mkdir $DIR/d73-2
9704         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9705         pid1=$!
9706
9707         lctl set_param fail_loc=0x80000129
9708         $MULTIOP $DIR/d73-1/f73-2 Oc &
9709         sleep 1
9710         lctl set_param fail_loc=0
9711
9712         $MULTIOP $DIR/d73-2/f73-3 Oc &
9713         pid3=$!
9714
9715         kill -USR1 $pid1
9716         wait $pid1 || return 1
9717
9718         sleep 25
9719
9720         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9721         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9722         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9723
9724         rm -rf $DIR/d73-*
9725 }
9726 run_test 73 "multiple MDC requests (should not deadlock)"
9727
9728 test_74a() { # bug 6149, 6184
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730
9731         touch $DIR/f74a
9732         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9733         #
9734         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9735         # will spin in a tight reconnection loop
9736         $LCTL set_param fail_loc=0x8000030e
9737         # get any lock that won't be difficult - lookup works.
9738         ls $DIR/f74a
9739         $LCTL set_param fail_loc=0
9740         rm -f $DIR/f74a
9741         true
9742 }
9743 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9744
9745 test_74b() { # bug 13310
9746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9747
9748         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9749         #
9750         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9751         # will spin in a tight reconnection loop
9752         $LCTL set_param fail_loc=0x8000030e
9753         # get a "difficult" lock
9754         touch $DIR/f74b
9755         $LCTL set_param fail_loc=0
9756         rm -f $DIR/f74b
9757         true
9758 }
9759 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9760
9761 test_74c() {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         #define OBD_FAIL_LDLM_NEW_LOCK
9765         $LCTL set_param fail_loc=0x319
9766         touch $DIR/$tfile && error "touch successful"
9767         $LCTL set_param fail_loc=0
9768         true
9769 }
9770 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9771
9772 slab_lic=/sys/kernel/slab/lustre_inode_cache
9773 num_objects() {
9774         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9775         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9776                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9777 }
9778
9779 test_76a() { # Now for b=20433, added originally in b=1443
9780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9781
9782         cancel_lru_locks osc
9783         # there may be some slab objects cached per core
9784         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9785         local before=$(num_objects)
9786         local count=$((512 * cpus))
9787         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9788         local margin=$((count / 10))
9789         if [[ -f $slab_lic/aliases ]]; then
9790                 local aliases=$(cat $slab_lic/aliases)
9791                 (( aliases > 0 )) && margin=$((margin * aliases))
9792         fi
9793
9794         echo "before slab objects: $before"
9795         for i in $(seq $count); do
9796                 touch $DIR/$tfile
9797                 rm -f $DIR/$tfile
9798         done
9799         cancel_lru_locks osc
9800         local after=$(num_objects)
9801         echo "created: $count, after slab objects: $after"
9802         # shared slab counts are not very accurate, allow significant margin
9803         # the main goal is that the cache growth is not permanently > $count
9804         while (( after > before + margin )); do
9805                 sleep 1
9806                 after=$(num_objects)
9807                 wait=$((wait + 1))
9808                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9809                 if (( wait > 60 )); then
9810                         error "inode slab grew from $before+$margin to $after"
9811                 fi
9812         done
9813 }
9814 run_test 76a "confirm clients recycle inodes properly ===="
9815
9816 test_76b() {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9819
9820         local count=512
9821         local before=$(num_objects)
9822
9823         for i in $(seq $count); do
9824                 mkdir $DIR/$tdir
9825                 rmdir $DIR/$tdir
9826         done
9827
9828         local after=$(num_objects)
9829         local wait=0
9830
9831         while (( after > before )); do
9832                 sleep 1
9833                 after=$(num_objects)
9834                 wait=$((wait + 1))
9835                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9836                 if (( wait > 60 )); then
9837                         error "inode slab grew from $before to $after"
9838                 fi
9839         done
9840
9841         echo "slab objects before: $before, after: $after"
9842 }
9843 run_test 76b "confirm clients recycle directory inodes properly ===="
9844
9845 export ORIG_CSUM=""
9846 set_checksums()
9847 {
9848         # Note: in sptlrpc modes which enable its own bulk checksum, the
9849         # original crc32_le bulk checksum will be automatically disabled,
9850         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9851         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9852         # In this case set_checksums() will not be no-op, because sptlrpc
9853         # bulk checksum will be enabled all through the test.
9854
9855         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9856         lctl set_param -n osc.*.checksums $1
9857         return 0
9858 }
9859
9860 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9861                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9862 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9863                              tr -d [] | head -n1)}
9864 set_checksum_type()
9865 {
9866         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9867         rc=$?
9868         log "set checksum type to $1, rc = $rc"
9869         return $rc
9870 }
9871
9872 get_osc_checksum_type()
9873 {
9874         # arugment 1: OST name, like OST0000
9875         ost=$1
9876         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9877                         sed 's/.*\[\(.*\)\].*/\1/g')
9878         rc=$?
9879         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9880         echo $checksum_type
9881 }
9882
9883 F77_TMP=$TMP/f77-temp
9884 F77SZ=8
9885 setup_f77() {
9886         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9887                 error "error writing to $F77_TMP"
9888 }
9889
9890 test_77a() { # bug 10889
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892         $GSS && skip_env "could not run with gss"
9893
9894         [ ! -f $F77_TMP ] && setup_f77
9895         set_checksums 1
9896         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9897         set_checksums 0
9898         rm -f $DIR/$tfile
9899 }
9900 run_test 77a "normal checksum read/write operation"
9901
9902 test_77b() { # bug 10889
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         [ ! -f $F77_TMP ] && setup_f77
9907         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9908         $LCTL set_param fail_loc=0x80000409
9909         set_checksums 1
9910
9911         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9912                 error "dd error: $?"
9913         $LCTL set_param fail_loc=0
9914
9915         for algo in $CKSUM_TYPES; do
9916                 cancel_lru_locks osc
9917                 set_checksum_type $algo
9918                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9919                 $LCTL set_param fail_loc=0x80000408
9920                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9921                 $LCTL set_param fail_loc=0
9922         done
9923         set_checksums 0
9924         set_checksum_type $ORIG_CSUM_TYPE
9925         rm -f $DIR/$tfile
9926 }
9927 run_test 77b "checksum error on client write, read"
9928
9929 cleanup_77c() {
9930         trap 0
9931         set_checksums 0
9932         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9933         $check_ost &&
9934                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9935         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9936         $check_ost && [ -n "$ost_file_prefix" ] &&
9937                 do_facet ost1 rm -f ${ost_file_prefix}\*
9938 }
9939
9940 test_77c() {
9941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9942         $GSS && skip_env "could not run with gss"
9943         remote_ost_nodsh && skip "remote OST with nodsh"
9944
9945         local bad1
9946         local osc_file_prefix
9947         local osc_file
9948         local check_ost=false
9949         local ost_file_prefix
9950         local ost_file
9951         local orig_cksum
9952         local dump_cksum
9953         local fid
9954
9955         # ensure corruption will occur on first OSS/OST
9956         $LFS setstripe -i 0 $DIR/$tfile
9957
9958         [ ! -f $F77_TMP ] && setup_f77
9959         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9960                 error "dd write error: $?"
9961         fid=$($LFS path2fid $DIR/$tfile)
9962
9963         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9964         then
9965                 check_ost=true
9966                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9967                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9968         else
9969                 echo "OSS do not support bulk pages dump upon error"
9970         fi
9971
9972         osc_file_prefix=$($LCTL get_param -n debug_path)
9973         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9974
9975         trap cleanup_77c EXIT
9976
9977         set_checksums 1
9978         # enable bulk pages dump upon error on Client
9979         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9980         # enable bulk pages dump upon error on OSS
9981         $check_ost &&
9982                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9983
9984         # flush Client cache to allow next read to reach OSS
9985         cancel_lru_locks osc
9986
9987         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9988         $LCTL set_param fail_loc=0x80000408
9989         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9990         $LCTL set_param fail_loc=0
9991
9992         rm -f $DIR/$tfile
9993
9994         # check cksum dump on Client
9995         osc_file=$(ls ${osc_file_prefix}*)
9996         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9997         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9998         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9999         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10000         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10001                      cksum)
10002         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10003         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10004                 error "dump content does not match on Client"
10005
10006         $check_ost || skip "No need to check cksum dump on OSS"
10007
10008         # check cksum dump on OSS
10009         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10010         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10011         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10012         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10013         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10014                 error "dump content does not match on OSS"
10015
10016         cleanup_77c
10017 }
10018 run_test 77c "checksum error on client read with debug"
10019
10020 test_77d() { # bug 10889
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         $GSS && skip_env "could not run with gss"
10023
10024         stack_trap "rm -f $DIR/$tfile"
10025         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10026         $LCTL set_param fail_loc=0x80000409
10027         set_checksums 1
10028         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10029                 error "direct write: rc=$?"
10030         $LCTL set_param fail_loc=0
10031         set_checksums 0
10032
10033         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10034         $LCTL set_param fail_loc=0x80000408
10035         set_checksums 1
10036         cancel_lru_locks osc
10037         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10038                 error "direct read: rc=$?"
10039         $LCTL set_param fail_loc=0
10040         set_checksums 0
10041 }
10042 run_test 77d "checksum error on OST direct write, read"
10043
10044 test_77f() { # bug 10889
10045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10046         $GSS && skip_env "could not run with gss"
10047
10048         set_checksums 1
10049         stack_trap "rm -f $DIR/$tfile"
10050         for algo in $CKSUM_TYPES; do
10051                 cancel_lru_locks osc
10052                 set_checksum_type $algo
10053                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10054                 $LCTL set_param fail_loc=0x409
10055                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10056                         error "direct write succeeded"
10057                 $LCTL set_param fail_loc=0
10058         done
10059         set_checksum_type $ORIG_CSUM_TYPE
10060         set_checksums 0
10061 }
10062 run_test 77f "repeat checksum error on write (expect error)"
10063
10064 test_77g() { # bug 10889
10065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10066         $GSS && skip_env "could not run with gss"
10067         remote_ost_nodsh && skip "remote OST with nodsh"
10068
10069         [ ! -f $F77_TMP ] && setup_f77
10070
10071         local file=$DIR/$tfile
10072         stack_trap "rm -f $file" EXIT
10073
10074         $LFS setstripe -c 1 -i 0 $file
10075         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10076         do_facet ost1 lctl set_param fail_loc=0x8000021a
10077         set_checksums 1
10078         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10079                 error "write error: rc=$?"
10080         do_facet ost1 lctl set_param fail_loc=0
10081         set_checksums 0
10082
10083         cancel_lru_locks osc
10084         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10085         do_facet ost1 lctl set_param fail_loc=0x8000021b
10086         set_checksums 1
10087         cmp $F77_TMP $file || error "file compare failed"
10088         do_facet ost1 lctl set_param fail_loc=0
10089         set_checksums 0
10090 }
10091 run_test 77g "checksum error on OST write, read"
10092
10093 test_77k() { # LU-10906
10094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10095         $GSS && skip_env "could not run with gss"
10096
10097         local cksum_param="osc.$FSNAME*.checksums"
10098         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10099         local checksum
10100         local i
10101
10102         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10103         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10104         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10105
10106         for i in 0 1; do
10107                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10108                         error "failed to set checksum=$i on MGS"
10109                 wait_update $HOSTNAME "$get_checksum" $i
10110                 #remount
10111                 echo "remount client, checksum should be $i"
10112                 remount_client $MOUNT || error "failed to remount client"
10113                 checksum=$(eval $get_checksum)
10114                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10115         done
10116         # remove persistent param to avoid races with checksum mountopt below
10117         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10118                 error "failed to delete checksum on MGS"
10119
10120         for opt in "checksum" "nochecksum"; do
10121                 #remount with mount option
10122                 echo "remount client with option $opt, checksum should be $i"
10123                 umount_client $MOUNT || error "failed to umount client"
10124                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10125                         error "failed to mount client with option '$opt'"
10126                 checksum=$(eval $get_checksum)
10127                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10128                 i=$((i - 1))
10129         done
10130
10131         remount_client $MOUNT || error "failed to remount client"
10132 }
10133 run_test 77k "enable/disable checksum correctly"
10134
10135 test_77l() {
10136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10137         $GSS && skip_env "could not run with gss"
10138
10139         set_checksums 1
10140         stack_trap "set_checksums $ORIG_CSUM" EXIT
10141         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10142
10143         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10144
10145         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10146         for algo in $CKSUM_TYPES; do
10147                 set_checksum_type $algo || error "fail to set checksum type $algo"
10148                 osc_algo=$(get_osc_checksum_type OST0000)
10149                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10150
10151                 # no locks, no reqs to let the connection idle
10152                 cancel_lru_locks osc
10153                 lru_resize_disable osc
10154                 wait_osc_import_state client ost1 IDLE
10155
10156                 # ensure ost1 is connected
10157                 stat $DIR/$tfile >/dev/null || error "can't stat"
10158                 wait_osc_import_state client ost1 FULL
10159
10160                 osc_algo=$(get_osc_checksum_type OST0000)
10161                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10162         done
10163         return 0
10164 }
10165 run_test 77l "preferred checksum type is remembered after reconnected"
10166
10167 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10168 rm -f $F77_TMP
10169 unset F77_TMP
10170
10171 test_77m() {
10172         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10173                 skip "Need at least version 2.14.52"
10174         local param=checksum_speed
10175
10176         $LCTL get_param $param || error "reading $param failed"
10177
10178         csum_speeds=$($LCTL get_param -n $param)
10179
10180         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10181                 error "known checksum types are missing"
10182 }
10183 run_test 77m "Verify checksum_speed is correctly read"
10184
10185 check_filefrag_77n() {
10186         local nr_ext=0
10187         local starts=()
10188         local ends=()
10189
10190         while read extidx a b start end rest; do
10191                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10192                         nr_ext=$(( $nr_ext + 1 ))
10193                         starts+=( ${start%..} )
10194                         ends+=( ${end%:} )
10195                 fi
10196         done < <( filefrag -sv $1 )
10197
10198         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10199         return 1
10200 }
10201
10202 test_77n() {
10203         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10204
10205         touch $DIR/$tfile
10206         $TRUNCATE $DIR/$tfile 0
10207         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10208         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10209         check_filefrag_77n $DIR/$tfile ||
10210                 skip "$tfile blocks not contiguous around hole"
10211
10212         set_checksums 1
10213         stack_trap "set_checksums $ORIG_CSUM" EXIT
10214         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10215         stack_trap "rm -f $DIR/$tfile"
10216
10217         for algo in $CKSUM_TYPES; do
10218                 if [[ "$algo" =~ ^t10 ]]; then
10219                         set_checksum_type $algo ||
10220                                 error "fail to set checksum type $algo"
10221                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10222                                 error "fail to read $tfile with $algo"
10223                 fi
10224         done
10225         rm -f $DIR/$tfile
10226         return 0
10227 }
10228 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10229
10230 test_77o() {
10231         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10232                 skip "Need MDS version at least 2.14.55"
10233         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10234                 skip "Need OST version at least 2.14.55"
10235         local ofd=obdfilter
10236         local mdt=mdt
10237
10238         # print OST checksum_type
10239         echo "$ofd.$FSNAME-*.checksum_type:"
10240         do_nodes $(comma_list $(osts_nodes)) \
10241                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10242
10243         # print MDT checksum_type
10244         echo "$mdt.$FSNAME-*.checksum_type:"
10245         do_nodes $(comma_list $(mdts_nodes)) \
10246                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10247
10248         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10249                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10250
10251         (( $o_count == $OSTCOUNT )) ||
10252                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10253
10254         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10255                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10256
10257         (( $m_count == $MDSCOUNT )) ||
10258                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10259 }
10260 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10261
10262 cleanup_test_78() {
10263         trap 0
10264         rm -f $DIR/$tfile
10265 }
10266
10267 test_78() { # bug 10901
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         remote_ost || skip_env "local OST"
10270
10271         NSEQ=5
10272         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10273         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10274         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10275         echo "MemTotal: $MEMTOTAL"
10276
10277         # reserve 256MB of memory for the kernel and other running processes,
10278         # and then take 1/2 of the remaining memory for the read/write buffers.
10279         if [ $MEMTOTAL -gt 512 ] ;then
10280                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10281         else
10282                 # for those poor memory-starved high-end clusters...
10283                 MEMTOTAL=$((MEMTOTAL / 2))
10284         fi
10285         echo "Mem to use for directio: $MEMTOTAL"
10286
10287         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10288         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10289         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10290         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10291                 head -n1)
10292         echo "Smallest OST: $SMALLESTOST"
10293         [[ $SMALLESTOST -lt 10240 ]] &&
10294                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10295
10296         trap cleanup_test_78 EXIT
10297
10298         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10299                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10300
10301         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10302         echo "File size: $F78SIZE"
10303         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10304         for i in $(seq 1 $NSEQ); do
10305                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10306                 echo directIO rdwr round $i of $NSEQ
10307                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10308         done
10309
10310         cleanup_test_78
10311 }
10312 run_test 78 "handle large O_DIRECT writes correctly ============"
10313
10314 test_79() { # bug 12743
10315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10316
10317         wait_delete_completed
10318
10319         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10320         BKFREE=$(calc_osc_kbytes kbytesfree)
10321         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10322
10323         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10324         DFTOTAL=`echo $STRING | cut -d, -f1`
10325         DFUSED=`echo $STRING  | cut -d, -f2`
10326         DFAVAIL=`echo $STRING | cut -d, -f3`
10327         DFFREE=$(($DFTOTAL - $DFUSED))
10328
10329         ALLOWANCE=$((64 * $OSTCOUNT))
10330
10331         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10332            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10333                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10334         fi
10335         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10336            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10337                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10338         fi
10339         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10340            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10341                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10342         fi
10343 }
10344 run_test 79 "df report consistency check ======================="
10345
10346 test_80() { # bug 10718
10347         remote_ost_nodsh && skip "remote OST with nodsh"
10348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10349
10350         # relax strong synchronous semantics for slow backends like ZFS
10351         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10352                 local soc="obdfilter.*.sync_lock_cancel"
10353                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10354
10355                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10356                 if [ -z "$save" ]; then
10357                         soc="obdfilter.*.sync_on_lock_cancel"
10358                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10359                 fi
10360
10361                 if [ "$save" != "never" ]; then
10362                         local hosts=$(comma_list $(osts_nodes))
10363
10364                         do_nodes $hosts $LCTL set_param $soc=never
10365                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10366                 fi
10367         fi
10368
10369         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10370         sync; sleep 1; sync
10371         local before=$(date +%s)
10372         cancel_lru_locks osc
10373         local after=$(date +%s)
10374         local diff=$((after - before))
10375         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10376
10377         rm -f $DIR/$tfile
10378 }
10379 run_test 80 "Page eviction is equally fast at high offsets too"
10380
10381 test_81a() { # LU-456
10382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10383         remote_ost_nodsh && skip "remote OST with nodsh"
10384
10385         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10386         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10387         do_facet ost1 lctl set_param fail_loc=0x80000228
10388
10389         # write should trigger a retry and success
10390         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10392         RC=$?
10393         if [ $RC -ne 0 ] ; then
10394                 error "write should success, but failed for $RC"
10395         fi
10396 }
10397 run_test 81a "OST should retry write when get -ENOSPC ==============="
10398
10399 test_81b() { # LU-456
10400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10401         remote_ost_nodsh && skip "remote OST with nodsh"
10402
10403         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10404         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10405         do_facet ost1 lctl set_param fail_loc=0x228
10406
10407         # write should retry several times and return -ENOSPC finally
10408         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10409         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10410         RC=$?
10411         ENOSPC=28
10412         if [ $RC -ne $ENOSPC ] ; then
10413                 error "dd should fail for -ENOSPC, but succeed."
10414         fi
10415 }
10416 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10417
10418 test_99() {
10419         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10420
10421         test_mkdir $DIR/$tdir.cvsroot
10422         chown $RUNAS_ID $DIR/$tdir.cvsroot
10423
10424         cd $TMP
10425         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10426
10427         cd /etc/init.d
10428         # some versions of cvs import exit(1) when asked to import links or
10429         # files they can't read.  ignore those files.
10430         local toignore=$(find . -type l -printf '-I %f\n' -o \
10431                          ! -perm /4 -printf '-I %f\n')
10432         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10433                 $tdir.reposname vtag rtag
10434
10435         cd $DIR
10436         test_mkdir $DIR/$tdir.reposname
10437         chown $RUNAS_ID $DIR/$tdir.reposname
10438         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10439
10440         cd $DIR/$tdir.reposname
10441         $RUNAS touch foo99
10442         $RUNAS cvs add -m 'addmsg' foo99
10443         $RUNAS cvs update
10444         $RUNAS cvs commit -m 'nomsg' foo99
10445         rm -fr $DIR/$tdir.cvsroot
10446 }
10447 run_test 99 "cvs strange file/directory operations"
10448
10449 test_100() {
10450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10451         [[ "$NETTYPE" =~ tcp ]] ||
10452                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10453         remote_ost_nodsh && skip "remote OST with nodsh"
10454         remote_mds_nodsh && skip "remote MDS with nodsh"
10455         remote_servers ||
10456                 skip "useless for local single node setup"
10457
10458         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10459                 [ "$PROT" != "tcp" ] && continue
10460                 RPORT=$(echo $REMOTE | cut -d: -f2)
10461                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10462
10463                 rc=0
10464                 LPORT=`echo $LOCAL | cut -d: -f2`
10465                 if [ $LPORT -ge 1024 ]; then
10466                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10467                         netstat -tna
10468                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10469                 fi
10470         done
10471         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10472 }
10473 run_test 100 "check local port using privileged port ==========="
10474
10475 function get_named_value()
10476 {
10477     local tag=$1
10478
10479     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10480 }
10481
10482 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10483                    awk '/^max_cached_mb/ { print $2 }')
10484
10485 cleanup_101a() {
10486         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10487         trap 0
10488 }
10489
10490 test_101a() {
10491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10492
10493         local s
10494         local discard
10495         local nreads=10000
10496         local cache_limit=32
10497
10498         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10499         trap cleanup_101a EXIT
10500         $LCTL set_param -n llite.*.read_ahead_stats=0
10501         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10502
10503         #
10504         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10505         #
10506         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10507         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10508
10509         discard=0
10510         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10511                    get_named_value 'read.but.discarded'); do
10512                         discard=$(($discard + $s))
10513         done
10514         cleanup_101a
10515
10516         $LCTL get_param osc.*-osc*.rpc_stats
10517         $LCTL get_param llite.*.read_ahead_stats
10518
10519         # Discard is generally zero, but sometimes a few random reads line up
10520         # and trigger larger readahead, which is wasted & leads to discards.
10521         if [[ $(($discard)) -gt $nreads ]]; then
10522                 error "too many ($discard) discarded pages"
10523         fi
10524         rm -f $DIR/$tfile || true
10525 }
10526 run_test 101a "check read-ahead for random reads"
10527
10528 setup_test101bc() {
10529         test_mkdir $DIR/$tdir
10530         local ssize=$1
10531         local FILE_LENGTH=$2
10532         STRIPE_OFFSET=0
10533
10534         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10535
10536         local list=$(comma_list $(osts_nodes))
10537         set_osd_param $list '' read_cache_enable 0
10538         set_osd_param $list '' writethrough_cache_enable 0
10539
10540         trap cleanup_test101bc EXIT
10541         # prepare the read-ahead file
10542         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10543
10544         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10545                                 count=$FILE_SIZE_MB 2> /dev/null
10546
10547 }
10548
10549 cleanup_test101bc() {
10550         trap 0
10551         rm -rf $DIR/$tdir
10552         rm -f $DIR/$tfile
10553
10554         local list=$(comma_list $(osts_nodes))
10555         set_osd_param $list '' read_cache_enable 1
10556         set_osd_param $list '' writethrough_cache_enable 1
10557 }
10558
10559 calc_total() {
10560         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10561 }
10562
10563 ra_check_101() {
10564         local read_size=$1
10565         local stripe_size=$2
10566         local stride_length=$((stripe_size / read_size))
10567         local stride_width=$((stride_length * OSTCOUNT))
10568         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10569                                 (stride_width - stride_length) ))
10570         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10571                   get_named_value 'read.but.discarded' | calc_total)
10572
10573         if [[ $discard -gt $discard_limit ]]; then
10574                 $LCTL get_param llite.*.read_ahead_stats
10575                 error "($discard) discarded pages with size (${read_size})"
10576         else
10577                 echo "Read-ahead success for size ${read_size}"
10578         fi
10579 }
10580
10581 test_101b() {
10582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10584
10585         local STRIPE_SIZE=1048576
10586         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10587
10588         if [ $SLOW == "yes" ]; then
10589                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10590         else
10591                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10592         fi
10593
10594         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10595
10596         # prepare the read-ahead file
10597         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10598         cancel_lru_locks osc
10599         for BIDX in 2 4 8 16 32 64 128 256
10600         do
10601                 local BSIZE=$((BIDX*4096))
10602                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10603                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10604                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10605                 $LCTL set_param -n llite.*.read_ahead_stats=0
10606                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10607                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10608                 cancel_lru_locks osc
10609                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10610         done
10611         cleanup_test101bc
10612         true
10613 }
10614 run_test 101b "check stride-io mode read-ahead ================="
10615
10616 test_101c() {
10617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10618
10619         local STRIPE_SIZE=1048576
10620         local FILE_LENGTH=$((STRIPE_SIZE*100))
10621         local nreads=10000
10622         local rsize=65536
10623         local osc_rpc_stats
10624
10625         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10626
10627         cancel_lru_locks osc
10628         $LCTL set_param osc.*.rpc_stats=0
10629         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10630         $LCTL get_param osc.*.rpc_stats
10631         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10632                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10633                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10634                 local size
10635
10636                 if [ $lines -le 20 ]; then
10637                         echo "continue debug"
10638                         continue
10639                 fi
10640                 for size in 1 2 4 8; do
10641                         local rpc=$(echo "$stats" |
10642                                     awk '($1 == "'$size':") {print $2; exit; }')
10643                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10644                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10645                 done
10646                 echo "$osc_rpc_stats check passed!"
10647         done
10648         cleanup_test101bc
10649         true
10650 }
10651 run_test 101c "check stripe_size aligned read-ahead"
10652
10653 test_101d() {
10654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10655
10656         local file=$DIR/$tfile
10657         local sz_MB=${FILESIZE_101d:-80}
10658         local ra_MB=${READAHEAD_MB:-40}
10659
10660         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10661         [ $free_MB -lt $sz_MB ] &&
10662                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10663
10664         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10665         $LFS setstripe -c -1 $file || error "setstripe failed"
10666
10667         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10668         echo Cancel LRU locks on lustre client to flush the client cache
10669         cancel_lru_locks osc
10670
10671         echo Disable read-ahead
10672         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10673         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10674         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10675         $LCTL get_param -n llite.*.max_read_ahead_mb
10676
10677         echo "Reading the test file $file with read-ahead disabled"
10678         local sz_KB=$((sz_MB * 1024 / 4))
10679         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10680         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10681         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10682                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10683
10684         echo "Cancel LRU locks on lustre client to flush the client cache"
10685         cancel_lru_locks osc
10686         echo Enable read-ahead with ${ra_MB}MB
10687         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10688
10689         echo "Reading the test file $file with read-ahead enabled"
10690         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10691                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10692
10693         echo "read-ahead disabled time read $raOFF"
10694         echo "read-ahead enabled time read $raON"
10695
10696         rm -f $file
10697         wait_delete_completed
10698
10699         # use awk for this check instead of bash because it handles decimals
10700         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10701                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10702 }
10703 run_test 101d "file read with and without read-ahead enabled"
10704
10705 test_101e() {
10706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10707
10708         local file=$DIR/$tfile
10709         local size_KB=500  #KB
10710         local count=100
10711         local bsize=1024
10712
10713         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10714         local need_KB=$((count * size_KB))
10715         [[ $free_KB -le $need_KB ]] &&
10716                 skip_env "Need free space $need_KB, have $free_KB"
10717
10718         echo "Creating $count ${size_KB}K test files"
10719         for ((i = 0; i < $count; i++)); do
10720                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10721         done
10722
10723         echo "Cancel LRU locks on lustre client to flush the client cache"
10724         cancel_lru_locks $OSC
10725
10726         echo "Reset readahead stats"
10727         $LCTL set_param -n llite.*.read_ahead_stats=0
10728
10729         for ((i = 0; i < $count; i++)); do
10730                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10731         done
10732
10733         $LCTL get_param llite.*.max_cached_mb
10734         $LCTL get_param llite.*.read_ahead_stats
10735         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10736                      get_named_value 'misses' | calc_total)
10737
10738         for ((i = 0; i < $count; i++)); do
10739                 rm -rf $file.$i 2>/dev/null
10740         done
10741
10742         #10000 means 20% reads are missing in readahead
10743         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10744 }
10745 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10746
10747 test_101f() {
10748         which iozone || skip_env "no iozone installed"
10749
10750         local old_debug=$($LCTL get_param debug)
10751         old_debug=${old_debug#*=}
10752         $LCTL set_param debug="reada mmap"
10753
10754         # create a test file
10755         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10756
10757         echo Cancel LRU locks on lustre client to flush the client cache
10758         cancel_lru_locks osc
10759
10760         echo Reset readahead stats
10761         $LCTL set_param -n llite.*.read_ahead_stats=0
10762
10763         echo mmap read the file with small block size
10764         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10765                 > /dev/null 2>&1
10766
10767         echo checking missing pages
10768         $LCTL get_param llite.*.read_ahead_stats
10769         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10770                         get_named_value 'misses' | calc_total)
10771
10772         $LCTL set_param debug="$old_debug"
10773         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10774         rm -f $DIR/$tfile
10775 }
10776 run_test 101f "check mmap read performance"
10777
10778 test_101g_brw_size_test() {
10779         local mb=$1
10780         local pages=$((mb * 1048576 / PAGE_SIZE))
10781         local file=$DIR/$tfile
10782
10783         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10784                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10785         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10786                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10787                         return 2
10788         done
10789
10790         stack_trap "rm -f $file" EXIT
10791         $LCTL set_param -n osc.*.rpc_stats=0
10792
10793         # 10 RPCs should be enough for the test
10794         local count=10
10795         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10796                 { error "dd write ${mb} MB blocks failed"; return 3; }
10797         cancel_lru_locks osc
10798         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10799                 { error "dd write ${mb} MB blocks failed"; return 4; }
10800
10801         # calculate number of full-sized read and write RPCs
10802         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10803                 sed -n '/pages per rpc/,/^$/p' |
10804                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10805                 END { print reads,writes }'))
10806         # allow one extra full-sized read RPC for async readahead
10807         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10808                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10809         [[ ${rpcs[1]} == $count ]] ||
10810                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10811 }
10812
10813 test_101g() {
10814         remote_ost_nodsh && skip "remote OST with nodsh"
10815
10816         local rpcs
10817         local osts=$(get_facets OST)
10818         local list=$(comma_list $(osts_nodes))
10819         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10820         local brw_size="obdfilter.*.brw_size"
10821
10822         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10823
10824         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10825
10826         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10827                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10828                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10829            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10830                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10831                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10832
10833                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10834                         suffix="M"
10835
10836                 if [[ $orig_mb -lt 16 ]]; then
10837                         save_lustre_params $osts "$brw_size" > $p
10838                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10839                                 error "set 16MB RPC size failed"
10840
10841                         echo "remount client to enable new RPC size"
10842                         remount_client $MOUNT || error "remount_client failed"
10843                 fi
10844
10845                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10846                 # should be able to set brw_size=12, but no rpc_stats for that
10847                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10848         fi
10849
10850         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10851
10852         if [[ $orig_mb -lt 16 ]]; then
10853                 restore_lustre_params < $p
10854                 remount_client $MOUNT || error "remount_client restore failed"
10855         fi
10856
10857         rm -f $p $DIR/$tfile
10858 }
10859 run_test 101g "Big bulk(4/16 MiB) readahead"
10860
10861 test_101h() {
10862         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10863
10864         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10865                 error "dd 70M file failed"
10866         echo Cancel LRU locks on lustre client to flush the client cache
10867         cancel_lru_locks osc
10868
10869         echo "Reset readahead stats"
10870         $LCTL set_param -n llite.*.read_ahead_stats 0
10871
10872         echo "Read 10M of data but cross 64M bundary"
10873         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10874         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10875                      get_named_value 'misses' | calc_total)
10876         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10877         rm -f $p $DIR/$tfile
10878 }
10879 run_test 101h "Readahead should cover current read window"
10880
10881 test_101i() {
10882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10883                 error "dd 10M file failed"
10884
10885         local max_per_file_mb=$($LCTL get_param -n \
10886                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10887         cancel_lru_locks osc
10888         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10889         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10890                 error "set max_read_ahead_per_file_mb to 1 failed"
10891
10892         echo "Reset readahead stats"
10893         $LCTL set_param llite.*.read_ahead_stats=0
10894
10895         dd if=$DIR/$tfile of=/dev/null bs=2M
10896
10897         $LCTL get_param llite.*.read_ahead_stats
10898         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10899                      awk '/misses/ { print $2 }')
10900         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10901         rm -f $DIR/$tfile
10902 }
10903 run_test 101i "allow current readahead to exceed reservation"
10904
10905 test_101j() {
10906         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10907                 error "setstripe $DIR/$tfile failed"
10908         local file_size=$((1048576 * 16))
10909         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10910         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10911
10912         echo Disable read-ahead
10913         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10914
10915         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10916         for blk in $PAGE_SIZE 1048576 $file_size; do
10917                 cancel_lru_locks osc
10918                 echo "Reset readahead stats"
10919                 $LCTL set_param -n llite.*.read_ahead_stats=0
10920                 local count=$(($file_size / $blk))
10921                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10922                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10923                              get_named_value 'failed.to.fast.read' | calc_total)
10924                 $LCTL get_param -n llite.*.read_ahead_stats
10925                 [ $miss -eq $count ] || error "expected $count got $miss"
10926         done
10927
10928         rm -f $p $DIR/$tfile
10929 }
10930 run_test 101j "A complete read block should be submitted when no RA"
10931
10932 setup_test102() {
10933         test_mkdir $DIR/$tdir
10934         chown $RUNAS_ID $DIR/$tdir
10935         STRIPE_SIZE=65536
10936         STRIPE_OFFSET=1
10937         STRIPE_COUNT=$OSTCOUNT
10938         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10939
10940         trap cleanup_test102 EXIT
10941         cd $DIR
10942         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10943         cd $DIR/$tdir
10944         for num in 1 2 3 4; do
10945                 for count in $(seq 1 $STRIPE_COUNT); do
10946                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10947                                 local size=`expr $STRIPE_SIZE \* $num`
10948                                 local file=file"$num-$idx-$count"
10949                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10950                         done
10951                 done
10952         done
10953
10954         cd $DIR
10955         $1 tar cf $TMP/f102.tar $tdir --xattrs
10956 }
10957
10958 cleanup_test102() {
10959         trap 0
10960         rm -f $TMP/f102.tar
10961         rm -rf $DIR/d0.sanity/d102
10962 }
10963
10964 test_102a() {
10965         [ "$UID" != 0 ] && skip "must run as root"
10966         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10967                 skip_env "must have user_xattr"
10968
10969         [ -z "$(which setfattr 2>/dev/null)" ] &&
10970                 skip_env "could not find setfattr"
10971
10972         local testfile=$DIR/$tfile
10973
10974         touch $testfile
10975         echo "set/get xattr..."
10976         setfattr -n trusted.name1 -v value1 $testfile ||
10977                 error "setfattr -n trusted.name1=value1 $testfile failed"
10978         getfattr -n trusted.name1 $testfile 2> /dev/null |
10979           grep "trusted.name1=.value1" ||
10980                 error "$testfile missing trusted.name1=value1"
10981
10982         setfattr -n user.author1 -v author1 $testfile ||
10983                 error "setfattr -n user.author1=author1 $testfile failed"
10984         getfattr -n user.author1 $testfile 2> /dev/null |
10985           grep "user.author1=.author1" ||
10986                 error "$testfile missing trusted.author1=author1"
10987
10988         echo "listxattr..."
10989         setfattr -n trusted.name2 -v value2 $testfile ||
10990                 error "$testfile unable to set trusted.name2"
10991         setfattr -n trusted.name3 -v value3 $testfile ||
10992                 error "$testfile unable to set trusted.name3"
10993         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10994             grep "trusted.name" | wc -l) -eq 3 ] ||
10995                 error "$testfile missing 3 trusted.name xattrs"
10996
10997         setfattr -n user.author2 -v author2 $testfile ||
10998                 error "$testfile unable to set user.author2"
10999         setfattr -n user.author3 -v author3 $testfile ||
11000                 error "$testfile unable to set user.author3"
11001         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11002             grep "user.author" | wc -l) -eq 3 ] ||
11003                 error "$testfile missing 3 user.author xattrs"
11004
11005         echo "remove xattr..."
11006         setfattr -x trusted.name1 $testfile ||
11007                 error "$testfile error deleting trusted.name1"
11008         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11009                 error "$testfile did not delete trusted.name1 xattr"
11010
11011         setfattr -x user.author1 $testfile ||
11012                 error "$testfile error deleting user.author1"
11013         echo "set lustre special xattr ..."
11014         $LFS setstripe -c1 $testfile
11015         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11016                 awk -F "=" '/trusted.lov/ { print $2 }' )
11017         setfattr -n "trusted.lov" -v $lovea $testfile ||
11018                 error "$testfile doesn't ignore setting trusted.lov again"
11019         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11020                 error "$testfile allow setting invalid trusted.lov"
11021         rm -f $testfile
11022 }
11023 run_test 102a "user xattr test =================================="
11024
11025 check_102b_layout() {
11026         local layout="$*"
11027         local testfile=$DIR/$tfile
11028
11029         echo "test layout '$layout'"
11030         $LFS setstripe $layout $testfile || error "setstripe failed"
11031         $LFS getstripe -y $testfile
11032
11033         echo "get/set/list trusted.lov xattr ..." # b=10930
11034         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11035         [[ "$value" =~ "trusted.lov" ]] ||
11036                 error "can't get trusted.lov from $testfile"
11037         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11038                 error "getstripe failed"
11039
11040         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11041
11042         value=$(cut -d= -f2 <<<$value)
11043         # LU-13168: truncated xattr should fail if short lov_user_md header
11044         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11045                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11046         for len in $lens; do
11047                 echo "setfattr $len $testfile.2"
11048                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11049                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11050         done
11051         local stripe_size=$($LFS getstripe -S $testfile.2)
11052         local stripe_count=$($LFS getstripe -c $testfile.2)
11053         [[ $stripe_size -eq 65536 ]] ||
11054                 error "stripe size $stripe_size != 65536"
11055         [[ $stripe_count -eq $stripe_count_orig ]] ||
11056                 error "stripe count $stripe_count != $stripe_count_orig"
11057         rm $testfile $testfile.2
11058 }
11059
11060 test_102b() {
11061         [ -z "$(which setfattr 2>/dev/null)" ] &&
11062                 skip_env "could not find setfattr"
11063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11064
11065         # check plain layout
11066         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11067
11068         # and also check composite layout
11069         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11070
11071 }
11072 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11073
11074 test_102c() {
11075         [ -z "$(which setfattr 2>/dev/null)" ] &&
11076                 skip_env "could not find setfattr"
11077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11078
11079         # b10930: get/set/list lustre.lov xattr
11080         echo "get/set/list lustre.lov xattr ..."
11081         test_mkdir $DIR/$tdir
11082         chown $RUNAS_ID $DIR/$tdir
11083         local testfile=$DIR/$tdir/$tfile
11084         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11085                 error "setstripe failed"
11086         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11087                 error "getstripe failed"
11088         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11089         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11090
11091         local testfile2=${testfile}2
11092         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11093                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11094
11095         $RUNAS $MCREATE $testfile2
11096         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11097         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11098         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11099         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11100         [ $stripe_count -eq $STRIPECOUNT ] ||
11101                 error "stripe count $stripe_count != $STRIPECOUNT"
11102 }
11103 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11104
11105 compare_stripe_info1() {
11106         local stripe_index_all_zero=true
11107
11108         for num in 1 2 3 4; do
11109                 for count in $(seq 1 $STRIPE_COUNT); do
11110                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11111                                 local size=$((STRIPE_SIZE * num))
11112                                 local file=file"$num-$offset-$count"
11113                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11114                                 [[ $stripe_size -ne $size ]] &&
11115                                     error "$file: size $stripe_size != $size"
11116                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11117                                 # allow fewer stripes to be created, ORI-601
11118                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11119                                     error "$file: count $stripe_count != $count"
11120                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11121                                 [[ $stripe_index -ne 0 ]] &&
11122                                         stripe_index_all_zero=false
11123                         done
11124                 done
11125         done
11126         $stripe_index_all_zero &&
11127                 error "all files are being extracted starting from OST index 0"
11128         return 0
11129 }
11130
11131 have_xattrs_include() {
11132         tar --help | grep -q xattrs-include &&
11133                 echo --xattrs-include="lustre.*"
11134 }
11135
11136 test_102d() {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11139
11140         XINC=$(have_xattrs_include)
11141         setup_test102
11142         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11143         cd $DIR/$tdir/$tdir
11144         compare_stripe_info1
11145 }
11146 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11147
11148 test_102f() {
11149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11151
11152         XINC=$(have_xattrs_include)
11153         setup_test102
11154         test_mkdir $DIR/$tdir.restore
11155         cd $DIR
11156         tar cf - --xattrs $tdir | tar xf - \
11157                 -C $DIR/$tdir.restore --xattrs $XINC
11158         cd $DIR/$tdir.restore/$tdir
11159         compare_stripe_info1
11160 }
11161 run_test 102f "tar copy files, not keep osts"
11162
11163 grow_xattr() {
11164         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11165                 skip "must have user_xattr"
11166         [ -z "$(which setfattr 2>/dev/null)" ] &&
11167                 skip_env "could not find setfattr"
11168         [ -z "$(which getfattr 2>/dev/null)" ] &&
11169                 skip_env "could not find getfattr"
11170
11171         local xsize=${1:-1024}  # in bytes
11172         local file=$DIR/$tfile
11173         local value="$(generate_string $xsize)"
11174         local xbig=trusted.big
11175         local toobig=$2
11176
11177         touch $file
11178         log "save $xbig on $file"
11179         if [ -z "$toobig" ]
11180         then
11181                 setfattr -n $xbig -v $value $file ||
11182                         error "saving $xbig on $file failed"
11183         else
11184                 setfattr -n $xbig -v $value $file &&
11185                         error "saving $xbig on $file succeeded"
11186                 return 0
11187         fi
11188
11189         local orig=$(get_xattr_value $xbig $file)
11190         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11191
11192         local xsml=trusted.sml
11193         log "save $xsml on $file"
11194         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11195
11196         local new=$(get_xattr_value $xbig $file)
11197         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11198
11199         log "grow $xsml on $file"
11200         setfattr -n $xsml -v "$value" $file ||
11201                 error "growing $xsml on $file failed"
11202
11203         new=$(get_xattr_value $xbig $file)
11204         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11205         log "$xbig still valid after growing $xsml"
11206
11207         rm -f $file
11208 }
11209
11210 test_102h() { # bug 15777
11211         grow_xattr 1024
11212 }
11213 run_test 102h "grow xattr from inside inode to external block"
11214
11215 test_102ha() {
11216         large_xattr_enabled || skip_env "ea_inode feature disabled"
11217
11218         echo "setting xattr of max xattr size: $(max_xattr_size)"
11219         grow_xattr $(max_xattr_size)
11220
11221         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11222         echo "This should fail:"
11223         grow_xattr $(($(max_xattr_size) + 10)) 1
11224 }
11225 run_test 102ha "grow xattr from inside inode to external inode"
11226
11227 test_102i() { # bug 17038
11228         [ -z "$(which getfattr 2>/dev/null)" ] &&
11229                 skip "could not find getfattr"
11230
11231         touch $DIR/$tfile
11232         ln -s $DIR/$tfile $DIR/${tfile}link
11233         getfattr -n trusted.lov $DIR/$tfile ||
11234                 error "lgetxattr on $DIR/$tfile failed"
11235         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11236                 grep -i "no such attr" ||
11237                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11238         rm -f $DIR/$tfile $DIR/${tfile}link
11239 }
11240 run_test 102i "lgetxattr test on symbolic link ============"
11241
11242 test_102j() {
11243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11244         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11245
11246         XINC=$(have_xattrs_include)
11247         setup_test102 "$RUNAS"
11248         chown $RUNAS_ID $DIR/$tdir
11249         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11250         cd $DIR/$tdir/$tdir
11251         compare_stripe_info1 "$RUNAS"
11252 }
11253 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11254
11255 test_102k() {
11256         [ -z "$(which setfattr 2>/dev/null)" ] &&
11257                 skip "could not find setfattr"
11258
11259         touch $DIR/$tfile
11260         # b22187 just check that does not crash for regular file.
11261         setfattr -n trusted.lov $DIR/$tfile
11262         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11263         local test_kdir=$DIR/$tdir
11264         test_mkdir $test_kdir
11265         local default_size=$($LFS getstripe -S $test_kdir)
11266         local default_count=$($LFS getstripe -c $test_kdir)
11267         local default_offset=$($LFS getstripe -i $test_kdir)
11268         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11269                 error 'dir setstripe failed'
11270         setfattr -n trusted.lov $test_kdir
11271         local stripe_size=$($LFS getstripe -S $test_kdir)
11272         local stripe_count=$($LFS getstripe -c $test_kdir)
11273         local stripe_offset=$($LFS getstripe -i $test_kdir)
11274         [ $stripe_size -eq $default_size ] ||
11275                 error "stripe size $stripe_size != $default_size"
11276         [ $stripe_count -eq $default_count ] ||
11277                 error "stripe count $stripe_count != $default_count"
11278         [ $stripe_offset -eq $default_offset ] ||
11279                 error "stripe offset $stripe_offset != $default_offset"
11280         rm -rf $DIR/$tfile $test_kdir
11281 }
11282 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11283
11284 test_102l() {
11285         [ -z "$(which getfattr 2>/dev/null)" ] &&
11286                 skip "could not find getfattr"
11287
11288         # LU-532 trusted. xattr is invisible to non-root
11289         local testfile=$DIR/$tfile
11290
11291         touch $testfile
11292
11293         echo "listxattr as user..."
11294         chown $RUNAS_ID $testfile
11295         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11296             grep -q "trusted" &&
11297                 error "$testfile trusted xattrs are user visible"
11298
11299         return 0;
11300 }
11301 run_test 102l "listxattr size test =================================="
11302
11303 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11304         local path=$DIR/$tfile
11305         touch $path
11306
11307         listxattr_size_check $path || error "listattr_size_check $path failed"
11308 }
11309 run_test 102m "Ensure listxattr fails on small bufffer ========"
11310
11311 cleanup_test102
11312
11313 getxattr() { # getxattr path name
11314         # Return the base64 encoding of the value of xattr name on path.
11315         local path=$1
11316         local name=$2
11317
11318         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11319         # file: $path
11320         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11321         #
11322         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11323
11324         getfattr --absolute-names --encoding=base64 --name=$name $path |
11325                 awk -F= -v name=$name '$1 == name {
11326                         print substr($0, index($0, "=") + 1);
11327         }'
11328 }
11329
11330 test_102n() { # LU-4101 mdt: protect internal xattrs
11331         [ -z "$(which setfattr 2>/dev/null)" ] &&
11332                 skip "could not find setfattr"
11333         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11334         then
11335                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11336         fi
11337
11338         local file0=$DIR/$tfile.0
11339         local file1=$DIR/$tfile.1
11340         local xattr0=$TMP/$tfile.0
11341         local xattr1=$TMP/$tfile.1
11342         local namelist="lov lma lmv link fid version som hsm"
11343         local name
11344         local value
11345
11346         rm -rf $file0 $file1 $xattr0 $xattr1
11347         touch $file0 $file1
11348
11349         # Get 'before' xattrs of $file1.
11350         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11351
11352         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11353                 namelist+=" lfsck_namespace"
11354         for name in $namelist; do
11355                 # Try to copy xattr from $file0 to $file1.
11356                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11357
11358                 setfattr --name=trusted.$name --value="$value" $file1 ||
11359                         error "setxattr 'trusted.$name' failed"
11360
11361                 # Try to set a garbage xattr.
11362                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11363
11364                 if [[ x$name == "xlov" ]]; then
11365                         setfattr --name=trusted.lov --value="$value" $file1 &&
11366                         error "setxattr invalid 'trusted.lov' success"
11367                 else
11368                         setfattr --name=trusted.$name --value="$value" $file1 ||
11369                                 error "setxattr invalid 'trusted.$name' failed"
11370                 fi
11371
11372                 # Try to remove the xattr from $file1. We don't care if this
11373                 # appears to succeed or fail, we just don't want there to be
11374                 # any changes or crashes.
11375                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11376         done
11377
11378         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11379         then
11380                 name="lfsck_ns"
11381                 # Try to copy xattr from $file0 to $file1.
11382                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11383
11384                 setfattr --name=trusted.$name --value="$value" $file1 ||
11385                         error "setxattr 'trusted.$name' failed"
11386
11387                 # Try to set a garbage xattr.
11388                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11389
11390                 setfattr --name=trusted.$name --value="$value" $file1 ||
11391                         error "setxattr 'trusted.$name' failed"
11392
11393                 # Try to remove the xattr from $file1. We don't care if this
11394                 # appears to succeed or fail, we just don't want there to be
11395                 # any changes or crashes.
11396                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11397         fi
11398
11399         # Get 'after' xattrs of file1.
11400         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11401
11402         if ! diff $xattr0 $xattr1; then
11403                 error "before and after xattrs of '$file1' differ"
11404         fi
11405
11406         rm -rf $file0 $file1 $xattr0 $xattr1
11407
11408         return 0
11409 }
11410 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11411
11412 test_102p() { # LU-4703 setxattr did not check ownership
11413         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11414                 skip "MDS needs to be at least 2.5.56"
11415
11416         local testfile=$DIR/$tfile
11417
11418         touch $testfile
11419
11420         echo "setfacl as user..."
11421         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11422         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11423
11424         echo "setfattr as user..."
11425         setfacl -m "u:$RUNAS_ID:---" $testfile
11426         $RUNAS setfattr -x system.posix_acl_access $testfile
11427         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11428 }
11429 run_test 102p "check setxattr(2) correctly fails without permission"
11430
11431 test_102q() {
11432         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11433                 skip "MDS needs to be at least 2.6.92"
11434
11435         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11436 }
11437 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11438
11439 test_102r() {
11440         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11441                 skip "MDS needs to be at least 2.6.93"
11442
11443         touch $DIR/$tfile || error "touch"
11444         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11445         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11446         rm $DIR/$tfile || error "rm"
11447
11448         #normal directory
11449         mkdir -p $DIR/$tdir || error "mkdir"
11450         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11451         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11452         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11453                 error "$testfile error deleting user.author1"
11454         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11455                 grep "user.$(basename $tdir)" &&
11456                 error "$tdir did not delete user.$(basename $tdir)"
11457         rmdir $DIR/$tdir || error "rmdir"
11458
11459         #striped directory
11460         test_mkdir $DIR/$tdir
11461         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11462         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11463         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11464                 error "$testfile error deleting user.author1"
11465         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11466                 grep "user.$(basename $tdir)" &&
11467                 error "$tdir did not delete user.$(basename $tdir)"
11468         rmdir $DIR/$tdir || error "rm striped dir"
11469 }
11470 run_test 102r "set EAs with empty values"
11471
11472 test_102s() {
11473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11474                 skip "MDS needs to be at least 2.11.52"
11475
11476         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11477
11478         save_lustre_params client "llite.*.xattr_cache" > $save
11479
11480         for cache in 0 1; do
11481                 lctl set_param llite.*.xattr_cache=$cache
11482
11483                 rm -f $DIR/$tfile
11484                 touch $DIR/$tfile || error "touch"
11485                 for prefix in lustre security system trusted user; do
11486                         # Note getxattr() may fail with 'Operation not
11487                         # supported' or 'No such attribute' depending
11488                         # on prefix and cache.
11489                         getfattr -n $prefix.n102s $DIR/$tfile &&
11490                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11491                 done
11492         done
11493
11494         restore_lustre_params < $save
11495 }
11496 run_test 102s "getting nonexistent xattrs should fail"
11497
11498 test_102t() {
11499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11500                 skip "MDS needs to be at least 2.11.52"
11501
11502         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11503
11504         save_lustre_params client "llite.*.xattr_cache" > $save
11505
11506         for cache in 0 1; do
11507                 lctl set_param llite.*.xattr_cache=$cache
11508
11509                 for buf_size in 0 256; do
11510                         rm -f $DIR/$tfile
11511                         touch $DIR/$tfile || error "touch"
11512                         setfattr -n user.multiop $DIR/$tfile
11513                         $MULTIOP $DIR/$tfile oa$buf_size ||
11514                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11515                 done
11516         done
11517
11518         restore_lustre_params < $save
11519 }
11520 run_test 102t "zero length xattr values handled correctly"
11521
11522 run_acl_subtest()
11523 {
11524     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11525     return $?
11526 }
11527
11528 test_103a() {
11529         [ "$UID" != 0 ] && skip "must run as root"
11530         $GSS && skip_env "could not run under gss"
11531         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11532                 skip_env "must have acl enabled"
11533         [ -z "$(which setfacl 2>/dev/null)" ] &&
11534                 skip_env "could not find setfacl"
11535         remote_mds_nodsh && skip "remote MDS with nodsh"
11536
11537         gpasswd -a daemon bin                           # LU-5641
11538         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11539
11540         declare -a identity_old
11541
11542         for num in $(seq $MDSCOUNT); do
11543                 switch_identity $num true || identity_old[$num]=$?
11544         done
11545
11546         SAVE_UMASK=$(umask)
11547         umask 0022
11548         mkdir -p $DIR/$tdir
11549         cd $DIR/$tdir
11550
11551         echo "performing cp ..."
11552         run_acl_subtest cp || error "run_acl_subtest cp failed"
11553         echo "performing getfacl-noacl..."
11554         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11555         echo "performing misc..."
11556         run_acl_subtest misc || error  "misc test failed"
11557         echo "performing permissions..."
11558         run_acl_subtest permissions || error "permissions failed"
11559         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11560         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11561                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11562                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11563         then
11564                 echo "performing permissions xattr..."
11565                 run_acl_subtest permissions_xattr ||
11566                         error "permissions_xattr failed"
11567         fi
11568         echo "performing setfacl..."
11569         run_acl_subtest setfacl || error  "setfacl test failed"
11570
11571         # inheritance test got from HP
11572         echo "performing inheritance..."
11573         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11574         chmod +x make-tree || error "chmod +x failed"
11575         run_acl_subtest inheritance || error "inheritance test failed"
11576         rm -f make-tree
11577
11578         echo "LU-974 ignore umask when acl is enabled..."
11579         run_acl_subtest 974 || error "LU-974 umask test failed"
11580         if [ $MDSCOUNT -ge 2 ]; then
11581                 run_acl_subtest 974_remote ||
11582                         error "LU-974 umask test failed under remote dir"
11583         fi
11584
11585         echo "LU-2561 newly created file is same size as directory..."
11586         if [ "$mds1_FSTYPE" != "zfs" ]; then
11587                 run_acl_subtest 2561 || error "LU-2561 test failed"
11588         else
11589                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11590         fi
11591
11592         run_acl_subtest 4924 || error "LU-4924 test failed"
11593
11594         cd $SAVE_PWD
11595         umask $SAVE_UMASK
11596
11597         for num in $(seq $MDSCOUNT); do
11598                 if [ "${identity_old[$num]}" = 1 ]; then
11599                         switch_identity $num false || identity_old[$num]=$?
11600                 fi
11601         done
11602 }
11603 run_test 103a "acl test"
11604
11605 test_103b() {
11606         declare -a pids
11607         local U
11608
11609         for U in {0..511}; do
11610                 {
11611                 local O=$(printf "%04o" $U)
11612
11613                 umask $(printf "%04o" $((511 ^ $O)))
11614                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11615                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11616
11617                 (( $S == ($O & 0666) )) ||
11618                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11619
11620                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11621                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11622                 (( $S == ($O & 0666) )) ||
11623                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11624
11625                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11626                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11627                 (( $S == ($O & 0666) )) ||
11628                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11629                 rm -f $DIR/$tfile.[smp]$0
11630                 } &
11631                 local pid=$!
11632
11633                 # limit the concurrently running threads to 64. LU-11878
11634                 local idx=$((U % 64))
11635                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11636                 pids[idx]=$pid
11637         done
11638         wait
11639 }
11640 run_test 103b "umask lfs setstripe"
11641
11642 test_103c() {
11643         mkdir -p $DIR/$tdir
11644         cp -rp $DIR/$tdir $DIR/$tdir.bak
11645
11646         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11647                 error "$DIR/$tdir shouldn't contain default ACL"
11648         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11649                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11650         true
11651 }
11652 run_test 103c "'cp -rp' won't set empty acl"
11653
11654 test_103e() {
11655         local numacl
11656         local fileacl
11657         local saved_debug=$($LCTL get_param -n debug)
11658
11659         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11660                 skip "MDS needs to be at least 2.14.52"
11661
11662         large_xattr_enabled || skip_env "ea_inode feature disabled"
11663
11664         mkdir -p $DIR/$tdir
11665         # add big LOV EA to cause reply buffer overflow earlier
11666         $LFS setstripe -C 1000 $DIR/$tdir
11667         lctl set_param mdc.*-mdc*.stats=clear
11668
11669         $LCTL set_param debug=0
11670         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11671         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11672
11673         # add a large number of default ACLs (expect 8000+ for 2.13+)
11674         for U in {2..7000}; do
11675                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11676                         error "Able to add just $U default ACLs"
11677         done
11678         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11679         echo "$numacl default ACLs created"
11680
11681         stat $DIR/$tdir || error "Cannot stat directory"
11682         # check file creation
11683         touch $DIR/$tdir/$tfile ||
11684                 error "failed to create $tfile with $numacl default ACLs"
11685         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11686         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11687         echo "$fileacl ACLs were inherited"
11688         (( $fileacl == $numacl )) ||
11689                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11690         # check that new ACLs creation adds new ACLs to inherited ACLs
11691         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11692                 error "Cannot set new ACL"
11693         numacl=$((numacl + 1))
11694         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11695         (( $fileacl == $numacl )) ||
11696                 error "failed to add new ACL: $fileacl != $numacl as expected"
11697         # adds more ACLs to a file to reach their maximum at 8000+
11698         numacl=0
11699         for U in {20000..25000}; do
11700                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11701                 numacl=$((numacl + 1))
11702         done
11703         echo "Added $numacl more ACLs to the file"
11704         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11705         echo "Total $fileacl ACLs in file"
11706         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11707         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11708         rmdir $DIR/$tdir || error "Cannot remove directory"
11709 }
11710 run_test 103e "inheritance of big amount of default ACLs"
11711
11712 test_103f() {
11713         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11714                 skip "MDS needs to be at least 2.14.51"
11715
11716         large_xattr_enabled || skip_env "ea_inode feature disabled"
11717
11718         # enable changelog to consume more internal MDD buffers
11719         changelog_register
11720
11721         mkdir -p $DIR/$tdir
11722         # add big LOV EA
11723         $LFS setstripe -C 1000 $DIR/$tdir
11724         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11725         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11726         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11727         rmdir $DIR/$tdir || error "Cannot remove directory"
11728 }
11729 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11730
11731 test_104a() {
11732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11733
11734         touch $DIR/$tfile
11735         lfs df || error "lfs df failed"
11736         lfs df -ih || error "lfs df -ih failed"
11737         lfs df -h $DIR || error "lfs df -h $DIR failed"
11738         lfs df -i $DIR || error "lfs df -i $DIR failed"
11739         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11740         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11741
11742         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11743         lctl --device %$OSC deactivate
11744         lfs df || error "lfs df with deactivated OSC failed"
11745         lctl --device %$OSC activate
11746         # wait the osc back to normal
11747         wait_osc_import_ready client ost
11748
11749         lfs df || error "lfs df with reactivated OSC failed"
11750         rm -f $DIR/$tfile
11751 }
11752 run_test 104a "lfs df [-ih] [path] test ========================="
11753
11754 test_104b() {
11755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11756         [ $RUNAS_ID -eq $UID ] &&
11757                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11758
11759         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11760                         grep "Permission denied" | wc -l)))
11761         if [ $denied_cnt -ne 0 ]; then
11762                 error "lfs check servers test failed"
11763         fi
11764 }
11765 run_test 104b "$RUNAS lfs check servers test ===================="
11766
11767 #
11768 # Verify $1 is within range of $2.
11769 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11770 # $1 is <= 2% of $2. Else Fail.
11771 #
11772 value_in_range() {
11773         # Strip all units (M, G, T)
11774         actual=$(echo $1 | tr -d A-Z)
11775         expect=$(echo $2 | tr -d A-Z)
11776
11777         expect_lo=$(($expect * 98 / 100)) # 2% below
11778         expect_hi=$(($expect * 102 / 100)) # 2% above
11779
11780         # permit 2% drift above and below
11781         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11782 }
11783
11784 test_104c() {
11785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11786         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11787
11788         local ost_param="osd-zfs.$FSNAME-OST0000."
11789         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11790         local ofacets=$(get_facets OST)
11791         local mfacets=$(get_facets MDS)
11792         local saved_ost_blocks=
11793         local saved_mdt_blocks=
11794
11795         echo "Before recordsize change"
11796         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11797         df=($(df -h | grep "$MOUNT"$))
11798
11799         # For checking.
11800         echo "lfs output : ${lfs_df[*]}"
11801         echo "df  output : ${df[*]}"
11802
11803         for facet in ${ofacets//,/ }; do
11804                 if [ -z $saved_ost_blocks ]; then
11805                         saved_ost_blocks=$(do_facet $facet \
11806                                 lctl get_param -n $ost_param.blocksize)
11807                         echo "OST Blocksize: $saved_ost_blocks"
11808                 fi
11809                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11810                 do_facet $facet zfs set recordsize=32768 $ost
11811         done
11812
11813         # BS too small. Sufficient for functional testing.
11814         for facet in ${mfacets//,/ }; do
11815                 if [ -z $saved_mdt_blocks ]; then
11816                         saved_mdt_blocks=$(do_facet $facet \
11817                                 lctl get_param -n $mdt_param.blocksize)
11818                         echo "MDT Blocksize: $saved_mdt_blocks"
11819                 fi
11820                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11821                 do_facet $facet zfs set recordsize=32768 $mdt
11822         done
11823
11824         # Give new values chance to reflect change
11825         sleep 2
11826
11827         echo "After recordsize change"
11828         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11829         df_after=($(df -h | grep "$MOUNT"$))
11830
11831         # For checking.
11832         echo "lfs output : ${lfs_df_after[*]}"
11833         echo "df  output : ${df_after[*]}"
11834
11835         # Verify lfs df
11836         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11837                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11838         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11839                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11840         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11841                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11842
11843         # Verify df
11844         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11845                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11846         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11847                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11848         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11849                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11850
11851         # Restore MDT recordize back to original
11852         for facet in ${mfacets//,/ }; do
11853                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11854                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11855         done
11856
11857         # Restore OST recordize back to original
11858         for facet in ${ofacets//,/ }; do
11859                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11860                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11861         done
11862
11863         return 0
11864 }
11865 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11866
11867 test_105a() {
11868         # doesn't work on 2.4 kernels
11869         touch $DIR/$tfile
11870         if $(flock_is_enabled); then
11871                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11872         else
11873                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11874         fi
11875         rm -f $DIR/$tfile
11876 }
11877 run_test 105a "flock when mounted without -o flock test ========"
11878
11879 test_105b() {
11880         touch $DIR/$tfile
11881         if $(flock_is_enabled); then
11882                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11883         else
11884                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11885         fi
11886         rm -f $DIR/$tfile
11887 }
11888 run_test 105b "fcntl when mounted without -o flock test ========"
11889
11890 test_105c() {
11891         touch $DIR/$tfile
11892         if $(flock_is_enabled); then
11893                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11894         else
11895                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11896         fi
11897         rm -f $DIR/$tfile
11898 }
11899 run_test 105c "lockf when mounted without -o flock test"
11900
11901 test_105d() { # bug 15924
11902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11903
11904         test_mkdir $DIR/$tdir
11905         flock_is_enabled || skip_env "mount w/o flock enabled"
11906         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11907         $LCTL set_param fail_loc=0x80000315
11908         flocks_test 2 $DIR/$tdir
11909 }
11910 run_test 105d "flock race (should not freeze) ========"
11911
11912 test_105e() { # bug 22660 && 22040
11913         flock_is_enabled || skip_env "mount w/o flock enabled"
11914
11915         touch $DIR/$tfile
11916         flocks_test 3 $DIR/$tfile
11917 }
11918 run_test 105e "Two conflicting flocks from same process"
11919
11920 test_106() { #bug 10921
11921         test_mkdir $DIR/$tdir
11922         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11923         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11924 }
11925 run_test 106 "attempt exec of dir followed by chown of that dir"
11926
11927 test_107() {
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929
11930         CDIR=`pwd`
11931         local file=core
11932
11933         cd $DIR
11934         rm -f $file
11935
11936         local save_pattern=$(sysctl -n kernel.core_pattern)
11937         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11938         sysctl -w kernel.core_pattern=$file
11939         sysctl -w kernel.core_uses_pid=0
11940
11941         ulimit -c unlimited
11942         sleep 60 &
11943         SLEEPPID=$!
11944
11945         sleep 1
11946
11947         kill -s 11 $SLEEPPID
11948         wait $SLEEPPID
11949         if [ -e $file ]; then
11950                 size=`stat -c%s $file`
11951                 [ $size -eq 0 ] && error "Fail to create core file $file"
11952         else
11953                 error "Fail to create core file $file"
11954         fi
11955         rm -f $file
11956         sysctl -w kernel.core_pattern=$save_pattern
11957         sysctl -w kernel.core_uses_pid=$save_uses_pid
11958         cd $CDIR
11959 }
11960 run_test 107 "Coredump on SIG"
11961
11962 test_110() {
11963         test_mkdir $DIR/$tdir
11964         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11965         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11966                 error "mkdir with 256 char should fail, but did not"
11967         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11968                 error "create with 255 char failed"
11969         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11970                 error "create with 256 char should fail, but did not"
11971
11972         ls -l $DIR/$tdir
11973         rm -rf $DIR/$tdir
11974 }
11975 run_test 110 "filename length checking"
11976
11977 #
11978 # Purpose: To verify dynamic thread (OSS) creation.
11979 #
11980 test_115() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982         remote_ost_nodsh && skip "remote OST with nodsh"
11983
11984         # Lustre does not stop service threads once they are started.
11985         # Reset number of running threads to default.
11986         stopall
11987         setupall
11988
11989         local OSTIO_pre
11990         local save_params="$TMP/sanity-$TESTNAME.parameters"
11991
11992         # Get ll_ost_io count before I/O
11993         OSTIO_pre=$(do_facet ost1 \
11994                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11995         # Exit if lustre is not running (ll_ost_io not running).
11996         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11997
11998         echo "Starting with $OSTIO_pre threads"
11999         local thread_max=$((OSTIO_pre * 2))
12000         local rpc_in_flight=$((thread_max * 2))
12001         # this is limited to OSC_MAX_RIF_MAX (256)
12002         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12003         thread_max=$((rpc_in_flight / 2))
12004         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12005                 return
12006
12007         # Number of I/O Process proposed to be started.
12008         local nfiles
12009         local facets=$(get_facets OST)
12010
12011         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12012         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12013
12014         # Set in_flight to $rpc_in_flight
12015         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12016                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12017         nfiles=${rpc_in_flight}
12018         # Set ost thread_max to $thread_max
12019         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12020
12021         # 5 Minutes should be sufficient for max number of OSS
12022         # threads(thread_max) to be created.
12023         local timeout=300
12024
12025         # Start I/O.
12026         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12027         test_mkdir $DIR/$tdir
12028         for i in $(seq $nfiles); do
12029                 local file=$DIR/$tdir/${tfile}-$i
12030                 $LFS setstripe -c -1 -i 0 $file
12031                 ($WTL $file $timeout)&
12032         done
12033
12034         # I/O Started - Wait for thread_started to reach thread_max or report
12035         # error if thread_started is more than thread_max.
12036         echo "Waiting for thread_started to reach thread_max"
12037         local thread_started=0
12038         local end_time=$((SECONDS + timeout))
12039
12040         while [ $SECONDS -le $end_time ] ; do
12041                 echo -n "."
12042                 # Get ost i/o thread_started count.
12043                 thread_started=$(do_facet ost1 \
12044                         "$LCTL get_param \
12045                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12046                 # Break out if thread_started is equal/greater than thread_max
12047                 if [[ $thread_started -ge $thread_max ]]; then
12048                         echo ll_ost_io thread_started $thread_started, \
12049                                 equal/greater than thread_max $thread_max
12050                         break
12051                 fi
12052                 sleep 1
12053         done
12054
12055         # Cleanup - We have the numbers, Kill i/o jobs if running.
12056         jobcount=($(jobs -p))
12057         for i in $(seq 0 $((${#jobcount[@]}-1)))
12058         do
12059                 kill -9 ${jobcount[$i]}
12060                 if [ $? -ne 0 ] ; then
12061                         echo Warning: \
12062                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12063                 fi
12064         done
12065
12066         # Cleanup files left by WTL binary.
12067         for i in $(seq $nfiles); do
12068                 local file=$DIR/$tdir/${tfile}-$i
12069                 rm -rf $file
12070                 if [ $? -ne 0 ] ; then
12071                         echo "Warning: Failed to delete file $file"
12072                 fi
12073         done
12074
12075         restore_lustre_params <$save_params
12076         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12077
12078         # Error out if no new thread has started or Thread started is greater
12079         # than thread max.
12080         if [[ $thread_started -le $OSTIO_pre ||
12081                         $thread_started -gt $thread_max ]]; then
12082                 error "ll_ost_io: thread_started $thread_started" \
12083                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12084                       "No new thread started or thread started greater " \
12085                       "than thread_max."
12086         fi
12087 }
12088 run_test 115 "verify dynamic thread creation===================="
12089
12090 test_116a() { # was previously test_116()
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12093         remote_mds_nodsh && skip "remote MDS with nodsh"
12094
12095         echo -n "Free space priority "
12096         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12097                 head -n1
12098         declare -a AVAIL
12099         free_min_max
12100
12101         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12102         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12103         stack_trap simple_cleanup_common
12104
12105         # Check if we need to generate uneven OSTs
12106         test_mkdir -p $DIR/$tdir/OST${MINI}
12107         local FILL=$((MINV / 4))
12108         local DIFF=$((MAXV - MINV))
12109         local DIFF2=$((DIFF * 100 / MINV))
12110
12111         local threshold=$(do_facet $SINGLEMDS \
12112                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12113         threshold=${threshold%%%}
12114         echo -n "Check for uneven OSTs: "
12115         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12116
12117         if [[ $DIFF2 -gt $threshold ]]; then
12118                 echo "ok"
12119                 echo "Don't need to fill OST$MINI"
12120         else
12121                 # generate uneven OSTs. Write 2% over the QOS threshold value
12122                 echo "no"
12123                 DIFF=$((threshold - DIFF2 + 2))
12124                 DIFF2=$((MINV * DIFF / 100))
12125                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12126                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12127                         error "setstripe failed"
12128                 DIFF=$((DIFF2 / 2048))
12129                 i=0
12130                 while [ $i -lt $DIFF ]; do
12131                         i=$((i + 1))
12132                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12133                                 bs=2M count=1 2>/dev/null
12134                         echo -n .
12135                 done
12136                 echo .
12137                 sync
12138                 sleep_maxage
12139                 free_min_max
12140         fi
12141
12142         DIFF=$((MAXV - MINV))
12143         DIFF2=$((DIFF * 100 / MINV))
12144         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12145         if [ $DIFF2 -gt $threshold ]; then
12146                 echo "ok"
12147         else
12148                 skip "QOS imbalance criteria not met"
12149         fi
12150
12151         MINI1=$MINI
12152         MINV1=$MINV
12153         MAXI1=$MAXI
12154         MAXV1=$MAXV
12155
12156         # now fill using QOS
12157         $LFS setstripe -c 1 $DIR/$tdir
12158         FILL=$((FILL / 200))
12159         if [ $FILL -gt 600 ]; then
12160                 FILL=600
12161         fi
12162         echo "writing $FILL files to QOS-assigned OSTs"
12163         i=0
12164         while [ $i -lt $FILL ]; do
12165                 i=$((i + 1))
12166                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12167                         count=1 2>/dev/null
12168                 echo -n .
12169         done
12170         echo "wrote $i 200k files"
12171         sync
12172         sleep_maxage
12173
12174         echo "Note: free space may not be updated, so measurements might be off"
12175         free_min_max
12176         DIFF2=$((MAXV - MINV))
12177         echo "free space delta: orig $DIFF final $DIFF2"
12178         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12179         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12180         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12181         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12182         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12183         if [[ $DIFF -gt 0 ]]; then
12184                 FILL=$((DIFF2 * 100 / DIFF - 100))
12185                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12186         fi
12187
12188         # Figure out which files were written where
12189         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12190                awk '/'$MINI1': / {print $2; exit}')
12191         echo $UUID
12192         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12193         echo "$MINC files created on smaller OST $MINI1"
12194         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12195                awk '/'$MAXI1': / {print $2; exit}')
12196         echo $UUID
12197         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12198         echo "$MAXC files created on larger OST $MAXI1"
12199         if [[ $MINC -gt 0 ]]; then
12200                 FILL=$((MAXC * 100 / MINC - 100))
12201                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12202         fi
12203         [[ $MAXC -gt $MINC ]] ||
12204                 error_ignore LU-9 "stripe QOS didn't balance free space"
12205 }
12206 run_test 116a "stripe QOS: free space balance ==================="
12207
12208 test_116b() { # LU-2093
12209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12210         remote_mds_nodsh && skip "remote MDS with nodsh"
12211
12212 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12213         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12214                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12215         [ -z "$old_rr" ] && skip "no QOS"
12216         do_facet $SINGLEMDS lctl set_param \
12217                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12218         mkdir -p $DIR/$tdir
12219         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12220         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12221         do_facet $SINGLEMDS lctl set_param fail_loc=0
12222         rm -rf $DIR/$tdir
12223         do_facet $SINGLEMDS lctl set_param \
12224                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12225 }
12226 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12227
12228 test_117() # bug 10891
12229 {
12230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12231
12232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12233         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12234         lctl set_param fail_loc=0x21e
12235         > $DIR/$tfile || error "truncate failed"
12236         lctl set_param fail_loc=0
12237         echo "Truncate succeeded."
12238         rm -f $DIR/$tfile
12239 }
12240 run_test 117 "verify osd extend =========="
12241
12242 NO_SLOW_RESENDCOUNT=4
12243 export OLD_RESENDCOUNT=""
12244 set_resend_count () {
12245         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12246         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12247         lctl set_param -n $PROC_RESENDCOUNT $1
12248         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12249 }
12250
12251 # for reduce test_118* time (b=14842)
12252 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12253
12254 # Reset async IO behavior after error case
12255 reset_async() {
12256         FILE=$DIR/reset_async
12257
12258         # Ensure all OSCs are cleared
12259         $LFS setstripe -c -1 $FILE
12260         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12261         sync
12262         rm $FILE
12263 }
12264
12265 test_118a() #bug 11710
12266 {
12267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12268
12269         reset_async
12270
12271         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12272         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12273         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12274
12275         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12276                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12277                 return 1;
12278         fi
12279         rm -f $DIR/$tfile
12280 }
12281 run_test 118a "verify O_SYNC works =========="
12282
12283 test_118b()
12284 {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286         remote_ost_nodsh && skip "remote OST with nodsh"
12287
12288         reset_async
12289
12290         #define OBD_FAIL_SRV_ENOENT 0x217
12291         set_nodes_failloc "$(osts_nodes)" 0x217
12292         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12293         RC=$?
12294         set_nodes_failloc "$(osts_nodes)" 0
12295         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12296         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12297                     grep -c writeback)
12298
12299         if [[ $RC -eq 0 ]]; then
12300                 error "Must return error due to dropped pages, rc=$RC"
12301                 return 1;
12302         fi
12303
12304         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12305                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12306                 return 1;
12307         fi
12308
12309         echo "Dirty pages not leaked on ENOENT"
12310
12311         # Due to the above error the OSC will issue all RPCs syncronously
12312         # until a subsequent RPC completes successfully without error.
12313         $MULTIOP $DIR/$tfile Ow4096yc
12314         rm -f $DIR/$tfile
12315
12316         return 0
12317 }
12318 run_test 118b "Reclaim dirty pages on fatal error =========="
12319
12320 test_118c()
12321 {
12322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12323
12324         # for 118c, restore the original resend count, LU-1940
12325         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12326                                 set_resend_count $OLD_RESENDCOUNT
12327         remote_ost_nodsh && skip "remote OST with nodsh"
12328
12329         reset_async
12330
12331         #define OBD_FAIL_OST_EROFS               0x216
12332         set_nodes_failloc "$(osts_nodes)" 0x216
12333
12334         # multiop should block due to fsync until pages are written
12335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12336         MULTIPID=$!
12337         sleep 1
12338
12339         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12340                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12341         fi
12342
12343         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12344                     grep -c writeback)
12345         if [[ $WRITEBACK -eq 0 ]]; then
12346                 error "No page in writeback, writeback=$WRITEBACK"
12347         fi
12348
12349         set_nodes_failloc "$(osts_nodes)" 0
12350         wait $MULTIPID
12351         RC=$?
12352         if [[ $RC -ne 0 ]]; then
12353                 error "Multiop fsync failed, rc=$RC"
12354         fi
12355
12356         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12357         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12358                     grep -c writeback)
12359         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12360                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12361         fi
12362
12363         rm -f $DIR/$tfile
12364         echo "Dirty pages flushed via fsync on EROFS"
12365         return 0
12366 }
12367 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12368
12369 # continue to use small resend count to reduce test_118* time (b=14842)
12370 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12371
12372 test_118d()
12373 {
12374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12375         remote_ost_nodsh && skip "remote OST with nodsh"
12376
12377         reset_async
12378
12379         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12380         set_nodes_failloc "$(osts_nodes)" 0x214
12381         # multiop should block due to fsync until pages are written
12382         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12383         MULTIPID=$!
12384         sleep 1
12385
12386         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12387                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12388         fi
12389
12390         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12391                     grep -c writeback)
12392         if [[ $WRITEBACK -eq 0 ]]; then
12393                 error "No page in writeback, writeback=$WRITEBACK"
12394         fi
12395
12396         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12397         set_nodes_failloc "$(osts_nodes)" 0
12398
12399         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12401                     grep -c writeback)
12402         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12403                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12404         fi
12405
12406         rm -f $DIR/$tfile
12407         echo "Dirty pages gaurenteed flushed via fsync"
12408         return 0
12409 }
12410 run_test 118d "Fsync validation inject a delay of the bulk =========="
12411
12412 test_118f() {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414
12415         reset_async
12416
12417         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12418         lctl set_param fail_loc=0x8000040a
12419
12420         # Should simulate EINVAL error which is fatal
12421         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12422         RC=$?
12423         if [[ $RC -eq 0 ]]; then
12424                 error "Must return error due to dropped pages, rc=$RC"
12425         fi
12426
12427         lctl set_param fail_loc=0x0
12428
12429         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12430         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12431         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12432                     grep -c writeback)
12433         if [[ $LOCKED -ne 0 ]]; then
12434                 error "Locked pages remain in cache, locked=$LOCKED"
12435         fi
12436
12437         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12438                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12439         fi
12440
12441         rm -f $DIR/$tfile
12442         echo "No pages locked after fsync"
12443
12444         reset_async
12445         return 0
12446 }
12447 run_test 118f "Simulate unrecoverable OSC side error =========="
12448
12449 test_118g() {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451
12452         reset_async
12453
12454         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12455         lctl set_param fail_loc=0x406
12456
12457         # simulate local -ENOMEM
12458         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12459         RC=$?
12460
12461         lctl set_param fail_loc=0
12462         if [[ $RC -eq 0 ]]; then
12463                 error "Must return error due to dropped pages, rc=$RC"
12464         fi
12465
12466         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12467         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12468         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12469                         grep -c writeback)
12470         if [[ $LOCKED -ne 0 ]]; then
12471                 error "Locked pages remain in cache, locked=$LOCKED"
12472         fi
12473
12474         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12475                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12476         fi
12477
12478         rm -f $DIR/$tfile
12479         echo "No pages locked after fsync"
12480
12481         reset_async
12482         return 0
12483 }
12484 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12485
12486 test_118h() {
12487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12488         remote_ost_nodsh && skip "remote OST with nodsh"
12489
12490         reset_async
12491
12492         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12493         set_nodes_failloc "$(osts_nodes)" 0x20e
12494         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12495         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12496         RC=$?
12497
12498         set_nodes_failloc "$(osts_nodes)" 0
12499         if [[ $RC -eq 0 ]]; then
12500                 error "Must return error due to dropped pages, rc=$RC"
12501         fi
12502
12503         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12504         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12505         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12506                     grep -c writeback)
12507         if [[ $LOCKED -ne 0 ]]; then
12508                 error "Locked pages remain in cache, locked=$LOCKED"
12509         fi
12510
12511         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12512                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12513         fi
12514
12515         rm -f $DIR/$tfile
12516         echo "No pages locked after fsync"
12517
12518         return 0
12519 }
12520 run_test 118h "Verify timeout in handling recoverables errors  =========="
12521
12522 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12523
12524 test_118i() {
12525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12526         remote_ost_nodsh && skip "remote OST with nodsh"
12527
12528         reset_async
12529
12530         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12531         set_nodes_failloc "$(osts_nodes)" 0x20e
12532
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         PID=$!
12536         sleep 5
12537         set_nodes_failloc "$(osts_nodes)" 0
12538
12539         wait $PID
12540         RC=$?
12541         if [[ $RC -ne 0 ]]; then
12542                 error "got error, but should be not, rc=$RC"
12543         fi
12544
12545         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12546         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12547         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12548         if [[ $LOCKED -ne 0 ]]; then
12549                 error "Locked pages remain in cache, locked=$LOCKED"
12550         fi
12551
12552         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12553                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12554         fi
12555
12556         rm -f $DIR/$tfile
12557         echo "No pages locked after fsync"
12558
12559         return 0
12560 }
12561 run_test 118i "Fix error before timeout in recoverable error  =========="
12562
12563 [ "$SLOW" = "no" ] && set_resend_count 4
12564
12565 test_118j() {
12566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12567         remote_ost_nodsh && skip "remote OST with nodsh"
12568
12569         reset_async
12570
12571         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12572         set_nodes_failloc "$(osts_nodes)" 0x220
12573
12574         # return -EIO from OST
12575         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12576         RC=$?
12577         set_nodes_failloc "$(osts_nodes)" 0x0
12578         if [[ $RC -eq 0 ]]; then
12579                 error "Must return error due to dropped pages, rc=$RC"
12580         fi
12581
12582         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12583         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12584         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12585         if [[ $LOCKED -ne 0 ]]; then
12586                 error "Locked pages remain in cache, locked=$LOCKED"
12587         fi
12588
12589         # in recoverable error on OST we want resend and stay until it finished
12590         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12591                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12592         fi
12593
12594         rm -f $DIR/$tfile
12595         echo "No pages locked after fsync"
12596
12597         return 0
12598 }
12599 run_test 118j "Simulate unrecoverable OST side error =========="
12600
12601 test_118k()
12602 {
12603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12604         remote_ost_nodsh && skip "remote OSTs with nodsh"
12605
12606         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12607         set_nodes_failloc "$(osts_nodes)" 0x20e
12608         test_mkdir $DIR/$tdir
12609
12610         for ((i=0;i<10;i++)); do
12611                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12612                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12613                 SLEEPPID=$!
12614                 sleep 0.500s
12615                 kill $SLEEPPID
12616                 wait $SLEEPPID
12617         done
12618
12619         set_nodes_failloc "$(osts_nodes)" 0
12620         rm -rf $DIR/$tdir
12621 }
12622 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12623
12624 test_118l() # LU-646
12625 {
12626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12627
12628         test_mkdir $DIR/$tdir
12629         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12630         rm -rf $DIR/$tdir
12631 }
12632 run_test 118l "fsync dir"
12633
12634 test_118m() # LU-3066
12635 {
12636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12637
12638         test_mkdir $DIR/$tdir
12639         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12640         rm -rf $DIR/$tdir
12641 }
12642 run_test 118m "fdatasync dir ========="
12643
12644 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12645
12646 test_118n()
12647 {
12648         local begin
12649         local end
12650
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652         remote_ost_nodsh && skip "remote OSTs with nodsh"
12653
12654         # Sleep to avoid a cached response.
12655         #define OBD_STATFS_CACHE_SECONDS 1
12656         sleep 2
12657
12658         # Inject a 10 second delay in the OST_STATFS handler.
12659         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12660         set_nodes_failloc "$(osts_nodes)" 0x242
12661
12662         begin=$SECONDS
12663         stat --file-system $MOUNT > /dev/null
12664         end=$SECONDS
12665
12666         set_nodes_failloc "$(osts_nodes)" 0
12667
12668         if ((end - begin > 20)); then
12669             error "statfs took $((end - begin)) seconds, expected 10"
12670         fi
12671 }
12672 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12673
12674 test_119a() # bug 11737
12675 {
12676         BSIZE=$((512 * 1024))
12677         directio write $DIR/$tfile 0 1 $BSIZE
12678         # We ask to read two blocks, which is more than a file size.
12679         # directio will indicate an error when requested and actual
12680         # sizes aren't equeal (a normal situation in this case) and
12681         # print actual read amount.
12682         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12683         if [ "$NOB" != "$BSIZE" ]; then
12684                 error "read $NOB bytes instead of $BSIZE"
12685         fi
12686         rm -f $DIR/$tfile
12687 }
12688 run_test 119a "Short directIO read must return actual read amount"
12689
12690 test_119b() # bug 11737
12691 {
12692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12693
12694         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12696         sync
12697         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12698                 error "direct read failed"
12699         rm -f $DIR/$tfile
12700 }
12701 run_test 119b "Sparse directIO read must return actual read amount"
12702
12703 test_119c() # bug 13099
12704 {
12705         BSIZE=1048576
12706         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12707         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12708         rm -f $DIR/$tfile
12709 }
12710 run_test 119c "Testing for direct read hitting hole"
12711
12712 test_119d() # bug 15950
12713 {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715
12716         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12717         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12718         BSIZE=1048576
12719         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12720         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12721         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12722         lctl set_param fail_loc=0x40d
12723         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12724         pid_dio=$!
12725         sleep 1
12726         cat $DIR/$tfile > /dev/null &
12727         lctl set_param fail_loc=0
12728         pid_reads=$!
12729         wait $pid_dio
12730         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12731         sleep 2
12732         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12733         error "the read rpcs have not completed in 2s"
12734         rm -f $DIR/$tfile
12735         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12736 }
12737 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12738
12739 test_120a() {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741         remote_mds_nodsh && skip "remote MDS with nodsh"
12742         test_mkdir -i0 -c1 $DIR/$tdir
12743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12744                 skip_env "no early lock cancel on server"
12745
12746         lru_resize_disable mdc
12747         lru_resize_disable osc
12748         cancel_lru_locks mdc
12749         # asynchronous object destroy at MDT could cause bl ast to client
12750         cancel_lru_locks osc
12751
12752         stat $DIR/$tdir > /dev/null
12753         can1=$(do_facet mds1 \
12754                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12755                awk '/ldlm_cancel/ {print $2}')
12756         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12757                awk '/ldlm_bl_callback/ {print $2}')
12758         test_mkdir -i0 -c1 $DIR/$tdir/d1
12759         can2=$(do_facet mds1 \
12760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12761                awk '/ldlm_cancel/ {print $2}')
12762         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12763                awk '/ldlm_bl_callback/ {print $2}')
12764         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12765         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12766         lru_resize_enable mdc
12767         lru_resize_enable osc
12768 }
12769 run_test 120a "Early Lock Cancel: mkdir test"
12770
12771 test_120b() {
12772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12773         remote_mds_nodsh && skip "remote MDS with nodsh"
12774         test_mkdir $DIR/$tdir
12775         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12776                 skip_env "no early lock cancel on server"
12777
12778         lru_resize_disable mdc
12779         lru_resize_disable osc
12780         cancel_lru_locks mdc
12781         stat $DIR/$tdir > /dev/null
12782         can1=$(do_facet $SINGLEMDS \
12783                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12784                awk '/ldlm_cancel/ {print $2}')
12785         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12786                awk '/ldlm_bl_callback/ {print $2}')
12787         touch $DIR/$tdir/f1
12788         can2=$(do_facet $SINGLEMDS \
12789                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12790                awk '/ldlm_cancel/ {print $2}')
12791         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12792                awk '/ldlm_bl_callback/ {print $2}')
12793         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12794         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12795         lru_resize_enable mdc
12796         lru_resize_enable osc
12797 }
12798 run_test 120b "Early Lock Cancel: create test"
12799
12800 test_120c() {
12801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12802         remote_mds_nodsh && skip "remote MDS with nodsh"
12803         test_mkdir -i0 -c1 $DIR/$tdir
12804         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12805                 skip "no early lock cancel on server"
12806
12807         lru_resize_disable mdc
12808         lru_resize_disable osc
12809         test_mkdir -i0 -c1 $DIR/$tdir/d1
12810         test_mkdir -i0 -c1 $DIR/$tdir/d2
12811         touch $DIR/$tdir/d1/f1
12812         cancel_lru_locks mdc
12813         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12814         can1=$(do_facet mds1 \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12820         can2=$(do_facet mds1 \
12821                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12822                awk '/ldlm_cancel/ {print $2}')
12823         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12824                awk '/ldlm_bl_callback/ {print $2}')
12825         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12826         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12827         lru_resize_enable mdc
12828         lru_resize_enable osc
12829 }
12830 run_test 120c "Early Lock Cancel: link test"
12831
12832 test_120d() {
12833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12834         remote_mds_nodsh && skip "remote MDS with nodsh"
12835         test_mkdir -i0 -c1 $DIR/$tdir
12836         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12837                 skip_env "no early lock cancel on server"
12838
12839         lru_resize_disable mdc
12840         lru_resize_disable osc
12841         touch $DIR/$tdir
12842         cancel_lru_locks mdc
12843         stat $DIR/$tdir > /dev/null
12844         can1=$(do_facet mds1 \
12845                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12846                awk '/ldlm_cancel/ {print $2}')
12847         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12848                awk '/ldlm_bl_callback/ {print $2}')
12849         chmod a+x $DIR/$tdir
12850         can2=$(do_facet mds1 \
12851                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12852                awk '/ldlm_cancel/ {print $2}')
12853         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12854                awk '/ldlm_bl_callback/ {print $2}')
12855         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12856         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12857         lru_resize_enable mdc
12858         lru_resize_enable osc
12859 }
12860 run_test 120d "Early Lock Cancel: setattr test"
12861
12862 test_120e() {
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12865                 skip_env "no early lock cancel on server"
12866         remote_mds_nodsh && skip "remote MDS with nodsh"
12867
12868         local dlmtrace_set=false
12869
12870         test_mkdir -i0 -c1 $DIR/$tdir
12871         lru_resize_disable mdc
12872         lru_resize_disable osc
12873         ! $LCTL get_param debug | grep -q dlmtrace &&
12874                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12875         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12876         cancel_lru_locks mdc
12877         cancel_lru_locks osc
12878         dd if=$DIR/$tdir/f1 of=/dev/null
12879         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12880         # XXX client can not do early lock cancel of OST lock
12881         # during unlink (LU-4206), so cancel osc lock now.
12882         sleep 2
12883         cancel_lru_locks osc
12884         can1=$(do_facet mds1 \
12885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12886                awk '/ldlm_cancel/ {print $2}')
12887         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12888                awk '/ldlm_bl_callback/ {print $2}')
12889         unlink $DIR/$tdir/f1
12890         sleep 5
12891         can2=$(do_facet mds1 \
12892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12893                awk '/ldlm_cancel/ {print $2}')
12894         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12895                awk '/ldlm_bl_callback/ {print $2}')
12896         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12897                 $LCTL dk $TMP/cancel.debug.txt
12898         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12899                 $LCTL dk $TMP/blocking.debug.txt
12900         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12901         lru_resize_enable mdc
12902         lru_resize_enable osc
12903 }
12904 run_test 120e "Early Lock Cancel: unlink test"
12905
12906 test_120f() {
12907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12908         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12909                 skip_env "no early lock cancel on server"
12910         remote_mds_nodsh && skip "remote MDS with nodsh"
12911
12912         test_mkdir -i0 -c1 $DIR/$tdir
12913         lru_resize_disable mdc
12914         lru_resize_disable osc
12915         test_mkdir -i0 -c1 $DIR/$tdir/d1
12916         test_mkdir -i0 -c1 $DIR/$tdir/d2
12917         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12918         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12919         cancel_lru_locks mdc
12920         cancel_lru_locks osc
12921         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12922         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12923         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12924         # XXX client can not do early lock cancel of OST lock
12925         # during rename (LU-4206), so cancel osc lock now.
12926         sleep 2
12927         cancel_lru_locks osc
12928         can1=$(do_facet mds1 \
12929                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12930                awk '/ldlm_cancel/ {print $2}')
12931         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12932                awk '/ldlm_bl_callback/ {print $2}')
12933         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12934         sleep 5
12935         can2=$(do_facet mds1 \
12936                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12937                awk '/ldlm_cancel/ {print $2}')
12938         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12939                awk '/ldlm_bl_callback/ {print $2}')
12940         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12941         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12942         lru_resize_enable mdc
12943         lru_resize_enable osc
12944 }
12945 run_test 120f "Early Lock Cancel: rename test"
12946
12947 test_120g() {
12948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12949         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12950                 skip_env "no early lock cancel on server"
12951         remote_mds_nodsh && skip "remote MDS with nodsh"
12952
12953         lru_resize_disable mdc
12954         lru_resize_disable osc
12955         count=10000
12956         echo create $count files
12957         test_mkdir $DIR/$tdir
12958         cancel_lru_locks mdc
12959         cancel_lru_locks osc
12960         t0=$(date +%s)
12961
12962         can0=$(do_facet $SINGLEMDS \
12963                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12964                awk '/ldlm_cancel/ {print $2}')
12965         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12966                awk '/ldlm_bl_callback/ {print $2}')
12967         createmany -o $DIR/$tdir/f $count
12968         sync
12969         can1=$(do_facet $SINGLEMDS \
12970                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12971                awk '/ldlm_cancel/ {print $2}')
12972         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12973                awk '/ldlm_bl_callback/ {print $2}')
12974         t1=$(date +%s)
12975         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12976         echo rm $count files
12977         rm -r $DIR/$tdir
12978         sync
12979         can2=$(do_facet $SINGLEMDS \
12980                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12981                awk '/ldlm_cancel/ {print $2}')
12982         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12983                awk '/ldlm_bl_callback/ {print $2}')
12984         t2=$(date +%s)
12985         echo total: $count removes in $((t2-t1))
12986         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12987         sleep 2
12988         # wait for commitment of removal
12989         lru_resize_enable mdc
12990         lru_resize_enable osc
12991 }
12992 run_test 120g "Early Lock Cancel: performance test"
12993
12994 test_121() { #bug #10589
12995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12996
12997         rm -rf $DIR/$tfile
12998         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12999 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13000         lctl set_param fail_loc=0x310
13001         cancel_lru_locks osc > /dev/null
13002         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13003         lctl set_param fail_loc=0
13004         [[ $reads -eq $writes ]] ||
13005                 error "read $reads blocks, must be $writes blocks"
13006 }
13007 run_test 121 "read cancel race ========="
13008
13009 test_123a_base() { # was test 123, statahead(bug 11401)
13010         local lsx="$1"
13011
13012         SLOWOK=0
13013         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13014                 log "testing UP system. Performance may be lower than expected."
13015                 SLOWOK=1
13016         fi
13017         running_in_vm && SLOWOK=1
13018
13019         rm -rf $DIR/$tdir
13020         test_mkdir $DIR/$tdir
13021         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13022         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13023         MULT=10
13024         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13025                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13026
13027                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13028                 lctl set_param -n llite.*.statahead_max 0
13029                 lctl get_param llite.*.statahead_max
13030                 cancel_lru_locks mdc
13031                 cancel_lru_locks osc
13032                 stime=$(date +%s)
13033                 time $lsx $DIR/$tdir | wc -l
13034                 etime=$(date +%s)
13035                 delta=$((etime - stime))
13036                 log "$lsx $i files without statahead: $delta sec"
13037                 lctl set_param llite.*.statahead_max=$max
13038
13039                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13040                         grep "statahead wrong:" | awk '{print $3}')
13041                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13042                 cancel_lru_locks mdc
13043                 cancel_lru_locks osc
13044                 stime=$(date +%s)
13045                 time $lsx $DIR/$tdir | wc -l
13046                 etime=$(date +%s)
13047                 delta_sa=$((etime - stime))
13048                 log "$lsx $i files with statahead: $delta_sa sec"
13049                 lctl get_param -n llite.*.statahead_stats
13050                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13051                         grep "statahead wrong:" | awk '{print $3}')
13052
13053                 [[ $swrong -lt $ewrong ]] &&
13054                         log "statahead was stopped, maybe too many locks held!"
13055                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13056
13057                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13058                         max=$(lctl get_param -n llite.*.statahead_max |
13059                                 head -n 1)
13060                         lctl set_param -n llite.*.statahead_max 0
13061                         lctl get_param llite.*.statahead_max
13062                         cancel_lru_locks mdc
13063                         cancel_lru_locks osc
13064                         stime=$(date +%s)
13065                         time $lsx $DIR/$tdir | wc -l
13066                         etime=$(date +%s)
13067                         delta=$((etime - stime))
13068                         log "$lsx $i files again without statahead: $delta sec"
13069                         lctl set_param llite.*.statahead_max=$max
13070                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13071                                 if [  $SLOWOK -eq 0 ]; then
13072                                         error "$lsx $i files is slower with statahead!"
13073                                 else
13074                                         log "$lsx $i files is slower with statahead!"
13075                                 fi
13076                                 break
13077                         fi
13078                 fi
13079
13080                 [ $delta -gt 20 ] && break
13081                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13082                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13083         done
13084         log "$lsx done"
13085
13086         stime=$(date +%s)
13087         rm -r $DIR/$tdir
13088         sync
13089         etime=$(date +%s)
13090         delta=$((etime - stime))
13091         log "rm -r $DIR/$tdir/: $delta seconds"
13092         log "rm done"
13093         lctl get_param -n llite.*.statahead_stats
13094 }
13095
13096 test_123aa() {
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098
13099         test_123a_base "ls -l"
13100 }
13101 run_test 123aa "verify statahead work"
13102
13103 test_123ab() {
13104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13105
13106         statx_supported || skip_env "Test must be statx() syscall supported"
13107
13108         test_123a_base "$STATX -l"
13109 }
13110 run_test 123ab "verify statahead work by using statx"
13111
13112 test_123ac() {
13113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13114
13115         statx_supported || skip_env "Test must be statx() syscall supported"
13116
13117         local rpcs_before
13118         local rpcs_after
13119         local agl_before
13120         local agl_after
13121
13122         cancel_lru_locks $OSC
13123         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13124         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13125                 awk '/agl.total:/ {print $3}')
13126         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13127         test_123a_base "$STATX --cached=always -D"
13128         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13129                 awk '/agl.total:/ {print $3}')
13130         [ $agl_before -eq $agl_after ] ||
13131                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13132         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13133         [ $rpcs_after -eq $rpcs_before ] ||
13134                 error "$STATX should not send glimpse RPCs to $OSC"
13135 }
13136 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13137
13138 test_123b () { # statahead(bug 15027)
13139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13140
13141         test_mkdir $DIR/$tdir
13142         createmany -o $DIR/$tdir/$tfile-%d 1000
13143
13144         cancel_lru_locks mdc
13145         cancel_lru_locks osc
13146
13147 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13148         lctl set_param fail_loc=0x80000803
13149         ls -lR $DIR/$tdir > /dev/null
13150         log "ls done"
13151         lctl set_param fail_loc=0x0
13152         lctl get_param -n llite.*.statahead_stats
13153         rm -r $DIR/$tdir
13154         sync
13155
13156 }
13157 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13158
13159 test_123c() {
13160         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13161
13162         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13163         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13164         touch $DIR/$tdir.1/{1..3}
13165         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13166
13167         remount_client $MOUNT
13168
13169         $MULTIOP $DIR/$tdir.0 Q
13170
13171         # let statahead to complete
13172         ls -l $DIR/$tdir.0 > /dev/null
13173
13174         testid=$(echo $TESTNAME | tr '_' ' ')
13175         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13176                 error "statahead warning" || true
13177 }
13178 run_test 123c "Can not initialize inode warning on DNE statahead"
13179
13180 test_124a() {
13181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13182         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13183                 skip_env "no lru resize on server"
13184
13185         local NR=2000
13186
13187         test_mkdir $DIR/$tdir
13188
13189         log "create $NR files at $DIR/$tdir"
13190         createmany -o $DIR/$tdir/f $NR ||
13191                 error "failed to create $NR files in $DIR/$tdir"
13192
13193         cancel_lru_locks mdc
13194         ls -l $DIR/$tdir > /dev/null
13195
13196         local NSDIR=""
13197         local LRU_SIZE=0
13198         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13199                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13200                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13201                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13202                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13203                         log "NSDIR=$NSDIR"
13204                         log "NS=$(basename $NSDIR)"
13205                         break
13206                 fi
13207         done
13208
13209         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13210                 skip "Not enough cached locks created!"
13211         fi
13212         log "LRU=$LRU_SIZE"
13213
13214         local SLEEP=30
13215
13216         # We know that lru resize allows one client to hold $LIMIT locks
13217         # for 10h. After that locks begin to be killed by client.
13218         local MAX_HRS=10
13219         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13220         log "LIMIT=$LIMIT"
13221         if [ $LIMIT -lt $LRU_SIZE ]; then
13222                 skip "Limit is too small $LIMIT"
13223         fi
13224
13225         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13226         # killing locks. Some time was spent for creating locks. This means
13227         # that up to the moment of sleep finish we must have killed some of
13228         # them (10-100 locks). This depends on how fast ther were created.
13229         # Many of them were touched in almost the same moment and thus will
13230         # be killed in groups.
13231         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13232
13233         # Use $LRU_SIZE_B here to take into account real number of locks
13234         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13235         local LRU_SIZE_B=$LRU_SIZE
13236         log "LVF=$LVF"
13237         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13238         log "OLD_LVF=$OLD_LVF"
13239         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13240
13241         # Let's make sure that we really have some margin. Client checks
13242         # cached locks every 10 sec.
13243         SLEEP=$((SLEEP+20))
13244         log "Sleep ${SLEEP} sec"
13245         local SEC=0
13246         while ((SEC<$SLEEP)); do
13247                 echo -n "..."
13248                 sleep 5
13249                 SEC=$((SEC+5))
13250                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13251                 echo -n "$LRU_SIZE"
13252         done
13253         echo ""
13254         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13255         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13256
13257         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13258                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13259                 unlinkmany $DIR/$tdir/f $NR
13260                 return
13261         }
13262
13263         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13264         log "unlink $NR files at $DIR/$tdir"
13265         unlinkmany $DIR/$tdir/f $NR
13266 }
13267 run_test 124a "lru resize ======================================="
13268
13269 get_max_pool_limit()
13270 {
13271         local limit=$($LCTL get_param \
13272                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13273         local max=0
13274         for l in $limit; do
13275                 if [[ $l -gt $max ]]; then
13276                         max=$l
13277                 fi
13278         done
13279         echo $max
13280 }
13281
13282 test_124b() {
13283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13284         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13285                 skip_env "no lru resize on server"
13286
13287         LIMIT=$(get_max_pool_limit)
13288
13289         NR=$(($(default_lru_size)*20))
13290         if [[ $NR -gt $LIMIT ]]; then
13291                 log "Limit lock number by $LIMIT locks"
13292                 NR=$LIMIT
13293         fi
13294
13295         IFree=$(mdsrate_inodes_available)
13296         if [ $IFree -lt $NR ]; then
13297                 log "Limit lock number by $IFree inodes"
13298                 NR=$IFree
13299         fi
13300
13301         lru_resize_disable mdc
13302         test_mkdir -p $DIR/$tdir/disable_lru_resize
13303
13304         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13305         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13306         cancel_lru_locks mdc
13307         stime=`date +%s`
13308         PID=""
13309         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13310         PID="$PID $!"
13311         sleep 2
13312         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13313         PID="$PID $!"
13314         sleep 2
13315         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13316         PID="$PID $!"
13317         wait $PID
13318         etime=`date +%s`
13319         nolruresize_delta=$((etime-stime))
13320         log "ls -la time: $nolruresize_delta seconds"
13321         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13322         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13323
13324         lru_resize_enable mdc
13325         test_mkdir -p $DIR/$tdir/enable_lru_resize
13326
13327         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13328         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13329         cancel_lru_locks mdc
13330         stime=`date +%s`
13331         PID=""
13332         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13333         PID="$PID $!"
13334         sleep 2
13335         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13336         PID="$PID $!"
13337         sleep 2
13338         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13339         PID="$PID $!"
13340         wait $PID
13341         etime=`date +%s`
13342         lruresize_delta=$((etime-stime))
13343         log "ls -la time: $lruresize_delta seconds"
13344         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13345
13346         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13347                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13348         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13349                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13350         else
13351                 log "lru resize performs the same with no lru resize"
13352         fi
13353         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13354 }
13355 run_test 124b "lru resize (performance test) ======================="
13356
13357 test_124c() {
13358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13359         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13360                 skip_env "no lru resize on server"
13361
13362         # cache ununsed locks on client
13363         local nr=100
13364         cancel_lru_locks mdc
13365         test_mkdir $DIR/$tdir
13366         createmany -o $DIR/$tdir/f $nr ||
13367                 error "failed to create $nr files in $DIR/$tdir"
13368         ls -l $DIR/$tdir > /dev/null
13369
13370         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13371         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13372         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13373         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13374         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13375
13376         # set lru_max_age to 1 sec
13377         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13378         echo "sleep $((recalc_p * 2)) seconds..."
13379         sleep $((recalc_p * 2))
13380
13381         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13382         # restore lru_max_age
13383         $LCTL set_param -n $nsdir.lru_max_age $max_age
13384         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13385         unlinkmany $DIR/$tdir/f $nr
13386 }
13387 run_test 124c "LRUR cancel very aged locks"
13388
13389 test_124d() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13392                 skip_env "no lru resize on server"
13393
13394         # cache ununsed locks on client
13395         local nr=100
13396
13397         lru_resize_disable mdc
13398         stack_trap "lru_resize_enable mdc" EXIT
13399
13400         cancel_lru_locks mdc
13401
13402         # asynchronous object destroy at MDT could cause bl ast to client
13403         test_mkdir $DIR/$tdir
13404         createmany -o $DIR/$tdir/f $nr ||
13405                 error "failed to create $nr files in $DIR/$tdir"
13406         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13407
13408         ls -l $DIR/$tdir > /dev/null
13409
13410         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13411         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13412         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13413         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13414
13415         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13416
13417         # set lru_max_age to 1 sec
13418         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13419         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13420
13421         echo "sleep $((recalc_p * 2)) seconds..."
13422         sleep $((recalc_p * 2))
13423
13424         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13425
13426         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13427 }
13428 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13429
13430 test_125() { # 13358
13431         $LCTL get_param -n llite.*.client_type | grep -q local ||
13432                 skip "must run as local client"
13433         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13434                 skip_env "must have acl enabled"
13435         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13436
13437         test_mkdir $DIR/$tdir
13438         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13439         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13440         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13441 }
13442 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13443
13444 test_126() { # bug 12829/13455
13445         $GSS && skip_env "must run as gss disabled"
13446         $LCTL get_param -n llite.*.client_type | grep -q local ||
13447                 skip "must run as local client"
13448         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13449
13450         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13451         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13452         rm -f $DIR/$tfile
13453         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13454 }
13455 run_test 126 "check that the fsgid provided by the client is taken into account"
13456
13457 test_127a() { # bug 15521
13458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13459         local name count samp unit min max sum sumsq
13460
13461         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13462         echo "stats before reset"
13463         $LCTL get_param osc.*.stats
13464         $LCTL set_param osc.*.stats=0
13465         local fsize=$((2048 * 1024))
13466
13467         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13468         cancel_lru_locks osc
13469         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13470
13471         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13472         stack_trap "rm -f $TMP/$tfile.tmp"
13473         while read name count samp unit min max sum sumsq; do
13474                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13475                 [ ! $min ] && error "Missing min value for $name proc entry"
13476                 eval $name=$count || error "Wrong proc format"
13477
13478                 case $name in
13479                 read_bytes|write_bytes)
13480                         [[ "$unit" =~ "bytes" ]] ||
13481                                 error "unit is not 'bytes': $unit"
13482                         (( $min >= 4096 )) || error "min is too small: $min"
13483                         (( $min <= $fsize )) || error "min is too big: $min"
13484                         (( $max >= 4096 )) || error "max is too small: $max"
13485                         (( $max <= $fsize )) || error "max is too big: $max"
13486                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13487                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13488                                 error "sumsquare is too small: $sumsq"
13489                         (( $sumsq <= $fsize * $fsize )) ||
13490                                 error "sumsquare is too big: $sumsq"
13491                         ;;
13492                 ost_read|ost_write)
13493                         [[ "$unit" =~ "usec" ]] ||
13494                                 error "unit is not 'usec': $unit"
13495                         ;;
13496                 *)      ;;
13497                 esac
13498         done < $DIR/$tfile.tmp
13499
13500         #check that we actually got some stats
13501         [ "$read_bytes" ] || error "Missing read_bytes stats"
13502         [ "$write_bytes" ] || error "Missing write_bytes stats"
13503         [ "$read_bytes" != 0 ] || error "no read done"
13504         [ "$write_bytes" != 0 ] || error "no write done"
13505 }
13506 run_test 127a "verify the client stats are sane"
13507
13508 test_127b() { # bug LU-333
13509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13510         local name count samp unit min max sum sumsq
13511
13512         echo "stats before reset"
13513         $LCTL get_param llite.*.stats
13514         $LCTL set_param llite.*.stats=0
13515
13516         # perform 2 reads and writes so MAX is different from SUM.
13517         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13518         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13519         cancel_lru_locks osc
13520         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13521         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13522
13523         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13524         stack_trap "rm -f $TMP/$tfile.tmp"
13525         while read name count samp unit min max sum sumsq; do
13526                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13527                 eval $name=$count || error "Wrong proc format"
13528
13529                 case $name in
13530                 read_bytes|write_bytes)
13531                         [[ "$unit" =~ "bytes" ]] ||
13532                                 error "unit is not 'bytes': $unit"
13533                         (( $count == 2 )) || error "count is not 2: $count"
13534                         (( $min == $PAGE_SIZE )) ||
13535                                 error "min is not $PAGE_SIZE: $min"
13536                         (( $max == $PAGE_SIZE )) ||
13537                                 error "max is not $PAGE_SIZE: $max"
13538                         (( $sum == $PAGE_SIZE * 2 )) ||
13539                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13540                         ;;
13541                 read|write)
13542                         [[ "$unit" =~ "usec" ]] ||
13543                                 error "unit is not 'usec': $unit"
13544                         ;;
13545                 *)      ;;
13546                 esac
13547         done < $TMP/$tfile.tmp
13548
13549         #check that we actually got some stats
13550         [ "$read_bytes" ] || error "Missing read_bytes stats"
13551         [ "$write_bytes" ] || error "Missing write_bytes stats"
13552         [ "$read_bytes" != 0 ] || error "no read done"
13553         [ "$write_bytes" != 0 ] || error "no write done"
13554 }
13555 run_test 127b "verify the llite client stats are sane"
13556
13557 test_127c() { # LU-12394
13558         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13559         local size
13560         local bsize
13561         local reads
13562         local writes
13563         local count
13564
13565         $LCTL set_param llite.*.extents_stats=1
13566         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13567
13568         # Use two stripes so there is enough space in default config
13569         $LFS setstripe -c 2 $DIR/$tfile
13570
13571         # Extent stats start at 0-4K and go in power of two buckets
13572         # LL_HIST_START = 12 --> 2^12 = 4K
13573         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13574         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13575         # small configs
13576         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13577                 do
13578                 # Write and read, 2x each, second time at a non-zero offset
13579                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13580                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13581                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13582                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13583                 rm -f $DIR/$tfile
13584         done
13585
13586         $LCTL get_param llite.*.extents_stats
13587
13588         count=2
13589         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13590                 do
13591                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13592                                 grep -m 1 $bsize)
13593                 reads=$(echo $bucket | awk '{print $5}')
13594                 writes=$(echo $bucket | awk '{print $9}')
13595                 [ "$reads" -eq $count ] ||
13596                         error "$reads reads in < $bsize bucket, expect $count"
13597                 [ "$writes" -eq $count ] ||
13598                         error "$writes writes in < $bsize bucket, expect $count"
13599         done
13600
13601         # Test mmap write and read
13602         $LCTL set_param llite.*.extents_stats=c
13603         size=512
13604         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13605         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13606         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13607
13608         $LCTL get_param llite.*.extents_stats
13609
13610         count=$(((size*1024) / PAGE_SIZE))
13611
13612         bsize=$((2 * PAGE_SIZE / 1024))K
13613
13614         bucket=$($LCTL get_param -n llite.*.extents_stats |
13615                         grep -m 1 $bsize)
13616         reads=$(echo $bucket | awk '{print $5}')
13617         writes=$(echo $bucket | awk '{print $9}')
13618         # mmap writes fault in the page first, creating an additonal read
13619         [ "$reads" -eq $((2 * count)) ] ||
13620                 error "$reads reads in < $bsize bucket, expect $count"
13621         [ "$writes" -eq $count ] ||
13622                 error "$writes writes in < $bsize bucket, expect $count"
13623 }
13624 run_test 127c "test llite extent stats with regular & mmap i/o"
13625
13626 test_128() { # bug 15212
13627         touch $DIR/$tfile
13628         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13629                 find $DIR/$tfile
13630                 find $DIR/$tfile
13631         EOF
13632
13633         result=$(grep error $TMP/$tfile.log)
13634         rm -f $DIR/$tfile $TMP/$tfile.log
13635         [ -z "$result" ] ||
13636                 error "consecutive find's under interactive lfs failed"
13637 }
13638 run_test 128 "interactive lfs for 2 consecutive find's"
13639
13640 set_dir_limits () {
13641         local mntdev
13642         local canondev
13643         local node
13644
13645         local ldproc=/proc/fs/ldiskfs
13646         local facets=$(get_facets MDS)
13647
13648         for facet in ${facets//,/ }; do
13649                 canondev=$(ldiskfs_canon \
13650                            *.$(convert_facet2label $facet).mntdev $facet)
13651                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13652                         ldproc=/sys/fs/ldiskfs
13653                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13654                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13655         done
13656 }
13657
13658 check_mds_dmesg() {
13659         local facets=$(get_facets MDS)
13660         for facet in ${facets//,/ }; do
13661                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13662         done
13663         return 1
13664 }
13665
13666 test_129() {
13667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13668         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13669                 skip "Need MDS version with at least 2.5.56"
13670         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13671                 skip_env "ldiskfs only test"
13672         fi
13673         remote_mds_nodsh && skip "remote MDS with nodsh"
13674
13675         local ENOSPC=28
13676         local has_warning=false
13677
13678         rm -rf $DIR/$tdir
13679         mkdir -p $DIR/$tdir
13680
13681         # block size of mds1
13682         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13683         set_dir_limits $maxsize $((maxsize * 6 / 8))
13684         stack_trap "set_dir_limits 0 0"
13685         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13686         local dirsize=$(stat -c%s "$DIR/$tdir")
13687         local nfiles=0
13688         while (( $dirsize <= $maxsize )); do
13689                 $MCREATE $DIR/$tdir/file_base_$nfiles
13690                 rc=$?
13691                 # check two errors:
13692                 # ENOSPC for ext4 max_dir_size, which has been used since
13693                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13694                 if (( rc == ENOSPC )); then
13695                         set_dir_limits 0 0
13696                         echo "rc=$rc returned as expected after $nfiles files"
13697
13698                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13699                                 error "create failed w/o dir size limit"
13700
13701                         # messages may be rate limited if test is run repeatedly
13702                         check_mds_dmesg '"is approaching max"' ||
13703                                 echo "warning message should be output"
13704                         check_mds_dmesg '"has reached max"' ||
13705                                 echo "reached message should be output"
13706
13707                         dirsize=$(stat -c%s "$DIR/$tdir")
13708
13709                         [[ $dirsize -ge $maxsize ]] && return 0
13710                         error "dirsize $dirsize < $maxsize after $nfiles files"
13711                 elif (( rc != 0 )); then
13712                         break
13713                 fi
13714                 nfiles=$((nfiles + 1))
13715                 dirsize=$(stat -c%s "$DIR/$tdir")
13716         done
13717
13718         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13719 }
13720 run_test 129 "test directory size limit ========================"
13721
13722 OLDIFS="$IFS"
13723 cleanup_130() {
13724         trap 0
13725         IFS="$OLDIFS"
13726 }
13727
13728 test_130a() {
13729         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13730         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13731
13732         trap cleanup_130 EXIT RETURN
13733
13734         local fm_file=$DIR/$tfile
13735         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13736         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13737                 error "dd failed for $fm_file"
13738
13739         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13740         filefrag -ves $fm_file
13741         RC=$?
13742         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13743                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13744         [ $RC != 0 ] && error "filefrag $fm_file failed"
13745
13746         filefrag_op=$(filefrag -ve -k $fm_file |
13747                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13748         lun=$($LFS getstripe -i $fm_file)
13749
13750         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13751         IFS=$'\n'
13752         tot_len=0
13753         for line in $filefrag_op
13754         do
13755                 frag_lun=`echo $line | cut -d: -f5`
13756                 ext_len=`echo $line | cut -d: -f4`
13757                 if (( $frag_lun != $lun )); then
13758                         cleanup_130
13759                         error "FIEMAP on 1-stripe file($fm_file) failed"
13760                         return
13761                 fi
13762                 (( tot_len += ext_len ))
13763         done
13764
13765         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13766                 cleanup_130
13767                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13768                 return
13769         fi
13770
13771         cleanup_130
13772
13773         echo "FIEMAP on single striped file succeeded"
13774 }
13775 run_test 130a "FIEMAP (1-stripe file)"
13776
13777 test_130b() {
13778         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13779
13780         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13781         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13782
13783         trap cleanup_130 EXIT RETURN
13784
13785         local fm_file=$DIR/$tfile
13786         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13787                         error "setstripe on $fm_file"
13788         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13789                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13790
13791         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13792                 error "dd failed on $fm_file"
13793
13794         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13795         filefrag_op=$(filefrag -ve -k $fm_file |
13796                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13797
13798         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13799                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13800
13801         IFS=$'\n'
13802         tot_len=0
13803         num_luns=1
13804         for line in $filefrag_op
13805         do
13806                 frag_lun=$(echo $line | cut -d: -f5 |
13807                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13808                 ext_len=$(echo $line | cut -d: -f4)
13809                 if (( $frag_lun != $last_lun )); then
13810                         if (( tot_len != 1024 )); then
13811                                 cleanup_130
13812                                 error "FIEMAP on $fm_file failed; returned " \
13813                                 "len $tot_len for OST $last_lun instead of 1024"
13814                                 return
13815                         else
13816                                 (( num_luns += 1 ))
13817                                 tot_len=0
13818                         fi
13819                 fi
13820                 (( tot_len += ext_len ))
13821                 last_lun=$frag_lun
13822         done
13823         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13824                 cleanup_130
13825                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13826                         "luns or wrong len for OST $last_lun"
13827                 return
13828         fi
13829
13830         cleanup_130
13831
13832         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13833 }
13834 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13835
13836 test_130c() {
13837         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13838
13839         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13840         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13841
13842         trap cleanup_130 EXIT RETURN
13843
13844         local fm_file=$DIR/$tfile
13845         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13846         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13847                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13848
13849         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13850                         error "dd failed on $fm_file"
13851
13852         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13853         filefrag_op=$(filefrag -ve -k $fm_file |
13854                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13855
13856         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13857                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13858
13859         IFS=$'\n'
13860         tot_len=0
13861         num_luns=1
13862         for line in $filefrag_op
13863         do
13864                 frag_lun=$(echo $line | cut -d: -f5 |
13865                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13866                 ext_len=$(echo $line | cut -d: -f4)
13867                 if (( $frag_lun != $last_lun )); then
13868                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13869                         if (( logical != 512 )); then
13870                                 cleanup_130
13871                                 error "FIEMAP on $fm_file failed; returned " \
13872                                 "logical start for lun $logical instead of 512"
13873                                 return
13874                         fi
13875                         if (( tot_len != 512 )); 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 != 2 || tot_len != 512 )); 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 2-stripe file with hole succeeded"
13898 }
13899 run_test 130c "FIEMAP (2-stripe file with hole)"
13900
13901 test_130d() {
13902         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 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 $OSTCOUNT $fm_file ||
13911                         error "setstripe on $fm_file"
13912         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13913                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13914
13915         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13916         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13917                 error "dd failed on $fm_file"
13918
13919         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13920         filefrag_op=$(filefrag -ve -k $fm_file |
13921                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13922
13923         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13924                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13925
13926         IFS=$'\n'
13927         tot_len=0
13928         num_luns=1
13929         for line in $filefrag_op
13930         do
13931                 frag_lun=$(echo $line | cut -d: -f5 |
13932                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13933                 ext_len=$(echo $line | cut -d: -f4)
13934                 if (( $frag_lun != $last_lun )); then
13935                         if (( tot_len != 1024 )); then
13936                                 cleanup_130
13937                                 error "FIEMAP on $fm_file failed; returned " \
13938                                 "len $tot_len for OST $last_lun instead of 1024"
13939                                 return
13940                         else
13941                                 (( num_luns += 1 ))
13942                                 tot_len=0
13943                         fi
13944                 fi
13945                 (( tot_len += ext_len ))
13946                 last_lun=$frag_lun
13947         done
13948         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13949                 cleanup_130
13950                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13951                         "luns or wrong len for OST $last_lun"
13952                 return
13953         fi
13954
13955         cleanup_130
13956
13957         echo "FIEMAP on N-stripe file succeeded"
13958 }
13959 run_test 130d "FIEMAP (N-stripe file)"
13960
13961 test_130e() {
13962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13963
13964         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13965         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13966
13967         trap cleanup_130 EXIT RETURN
13968
13969         local fm_file=$DIR/$tfile
13970         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13971
13972         NUM_BLKS=512
13973         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13974         for ((i = 0; i < $NUM_BLKS; i++)); do
13975                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13976                         conv=notrunc > /dev/null 2>&1
13977         done
13978
13979         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13980         filefrag_op=$(filefrag -ve -k $fm_file |
13981                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13982
13983         last_lun=$(echo $filefrag_op | cut -d: -f5)
13984
13985         IFS=$'\n'
13986         tot_len=0
13987         num_luns=1
13988         for line in $filefrag_op; do
13989                 frag_lun=$(echo $line | cut -d: -f5)
13990                 ext_len=$(echo $line | cut -d: -f4)
13991                 if [[ "$frag_lun" != "$last_lun" ]]; then
13992                         if (( tot_len != $EXPECTED_LEN )); then
13993                                 cleanup_130
13994                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13995                         else
13996                                 (( num_luns += 1 ))
13997                                 tot_len=0
13998                         fi
13999                 fi
14000                 (( tot_len += ext_len ))
14001                 last_lun=$frag_lun
14002         done
14003         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14004                 cleanup_130
14005                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14006         fi
14007
14008         echo "FIEMAP with continuation calls succeeded"
14009 }
14010 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14011
14012 test_130f() {
14013         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14014         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14015
14016         local fm_file=$DIR/$tfile
14017         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14018                 error "multiop create with lov_delay_create on $fm_file"
14019
14020         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14021         filefrag_extents=$(filefrag -vek $fm_file |
14022                            awk '/extents? found/ { print $2 }')
14023         if [[ "$filefrag_extents" != "0" ]]; then
14024                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14025         fi
14026
14027         rm -f $fm_file
14028 }
14029 run_test 130f "FIEMAP (unstriped file)"
14030
14031 test_130g() {
14032         local file=$DIR/$tfile
14033         local nr=$((OSTCOUNT * 100))
14034
14035         $LFS setstripe -C $nr $file ||
14036                 error "failed to setstripe -C $nr $file"
14037
14038         dd if=/dev/zero of=$file count=$nr bs=1M
14039         sync
14040         nr=$($LFS getstripe -c $file)
14041
14042         local extents=$(filefrag -v $file |
14043                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14044
14045         echo "filefrag list $extents extents in file with stripecount $nr"
14046         if (( extents < nr )); then
14047                 $LFS getstripe $file
14048                 filefrag -v $file
14049                 error "filefrag printed $extents < $nr extents"
14050         fi
14051
14052         rm -f $file
14053 }
14054 run_test 130g "FIEMAP (overstripe file)"
14055
14056 # Test for writev/readv
14057 test_131a() {
14058         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14059                 error "writev test failed"
14060         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14061                 error "readv failed"
14062         rm -f $DIR/$tfile
14063 }
14064 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14065
14066 test_131b() {
14067         local fsize=$((524288 + 1048576 + 1572864))
14068         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14069                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14070                         error "append writev test failed"
14071
14072         ((fsize += 1572864 + 1048576))
14073         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14074                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14075                         error "append writev test failed"
14076         rm -f $DIR/$tfile
14077 }
14078 run_test 131b "test append writev"
14079
14080 test_131c() {
14081         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14082         error "NOT PASS"
14083 }
14084 run_test 131c "test read/write on file w/o objects"
14085
14086 test_131d() {
14087         rwv -f $DIR/$tfile -w -n 1 1572864
14088         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14089         if [ "$NOB" != 1572864 ]; then
14090                 error "Short read filed: read $NOB bytes instead of 1572864"
14091         fi
14092         rm -f $DIR/$tfile
14093 }
14094 run_test 131d "test short read"
14095
14096 test_131e() {
14097         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14098         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14099         error "read hitting hole failed"
14100         rm -f $DIR/$tfile
14101 }
14102 run_test 131e "test read hitting hole"
14103
14104 check_stats() {
14105         local facet=$1
14106         local op=$2
14107         local want=${3:-0}
14108         local res
14109
14110         case $facet in
14111         mds*) res=$(do_facet $facet \
14112                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14113                  ;;
14114         ost*) res=$(do_facet $facet \
14115                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14116                  ;;
14117         *) error "Wrong facet '$facet'" ;;
14118         esac
14119         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14120         # if the argument $3 is zero, it means any stat increment is ok.
14121         if [[ $want -gt 0 ]]; then
14122                 local count=$(echo $res | awk '{ print $2 }')
14123                 [[ $count -ne $want ]] &&
14124                         error "The $op counter on $facet is $count, not $want"
14125         fi
14126 }
14127
14128 test_133a() {
14129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14130         remote_ost_nodsh && skip "remote OST with nodsh"
14131         remote_mds_nodsh && skip "remote MDS with nodsh"
14132         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14133                 skip_env "MDS doesn't support rename stats"
14134
14135         local testdir=$DIR/${tdir}/stats_testdir
14136
14137         mkdir -p $DIR/${tdir}
14138
14139         # clear stats.
14140         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14141         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14142
14143         # verify mdt stats first.
14144         mkdir ${testdir} || error "mkdir failed"
14145         check_stats $SINGLEMDS "mkdir" 1
14146         touch ${testdir}/${tfile} || error "touch failed"
14147         check_stats $SINGLEMDS "open" 1
14148         check_stats $SINGLEMDS "close" 1
14149         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14150                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14151                 check_stats $SINGLEMDS "mknod" 2
14152         }
14153         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14154         check_stats $SINGLEMDS "unlink" 1
14155         rm -f ${testdir}/${tfile} || error "file remove failed"
14156         check_stats $SINGLEMDS "unlink" 2
14157
14158         # remove working dir and check mdt stats again.
14159         rmdir ${testdir} || error "rmdir failed"
14160         check_stats $SINGLEMDS "rmdir" 1
14161
14162         local testdir1=$DIR/${tdir}/stats_testdir1
14163         mkdir -p ${testdir}
14164         mkdir -p ${testdir1}
14165         touch ${testdir1}/test1
14166         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14167         check_stats $SINGLEMDS "crossdir_rename" 1
14168
14169         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14170         check_stats $SINGLEMDS "samedir_rename" 1
14171
14172         rm -rf $DIR/${tdir}
14173 }
14174 run_test 133a "Verifying MDT stats ========================================"
14175
14176 test_133b() {
14177         local res
14178
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180         remote_ost_nodsh && skip "remote OST with nodsh"
14181         remote_mds_nodsh && skip "remote MDS with nodsh"
14182
14183         local testdir=$DIR/${tdir}/stats_testdir
14184
14185         mkdir -p ${testdir} || error "mkdir failed"
14186         touch ${testdir}/${tfile} || error "touch failed"
14187         cancel_lru_locks mdc
14188
14189         # clear stats.
14190         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14191         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14192
14193         # extra mdt stats verification.
14194         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14195         check_stats $SINGLEMDS "setattr" 1
14196         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14197         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14198         then            # LU-1740
14199                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14200                 check_stats $SINGLEMDS "getattr" 1
14201         fi
14202         rm -rf $DIR/${tdir}
14203
14204         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14205         # so the check below is not reliable
14206         [ $MDSCOUNT -eq 1 ] || return 0
14207
14208         # Sleep to avoid a cached response.
14209         #define OBD_STATFS_CACHE_SECONDS 1
14210         sleep 2
14211         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14212         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14213         $LFS df || error "lfs failed"
14214         check_stats $SINGLEMDS "statfs" 1
14215
14216         # check aggregated statfs (LU-10018)
14217         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14218                 return 0
14219         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14220                 return 0
14221         sleep 2
14222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14223         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14224         df $DIR
14225         check_stats $SINGLEMDS "statfs" 1
14226
14227         # We want to check that the client didn't send OST_STATFS to
14228         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14229         # extra care is needed here.
14230         if remote_mds; then
14231                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14232                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14233
14234                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14235                 [ "$res" ] && error "OST got STATFS"
14236         fi
14237
14238         return 0
14239 }
14240 run_test 133b "Verifying extra MDT stats =================================="
14241
14242 test_133c() {
14243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14244         remote_ost_nodsh && skip "remote OST with nodsh"
14245         remote_mds_nodsh && skip "remote MDS with nodsh"
14246
14247         local testdir=$DIR/$tdir/stats_testdir
14248
14249         test_mkdir -p $testdir
14250
14251         # verify obdfilter stats.
14252         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14253         sync
14254         cancel_lru_locks osc
14255         wait_delete_completed
14256
14257         # clear stats.
14258         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14259         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14260
14261         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14262                 error "dd failed"
14263         sync
14264         cancel_lru_locks osc
14265         check_stats ost1 "write" 1
14266
14267         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14268         check_stats ost1 "read" 1
14269
14270         > $testdir/$tfile || error "truncate failed"
14271         check_stats ost1 "punch" 1
14272
14273         rm -f $testdir/$tfile || error "file remove failed"
14274         wait_delete_completed
14275         check_stats ost1 "destroy" 1
14276
14277         rm -rf $DIR/$tdir
14278 }
14279 run_test 133c "Verifying OST stats ========================================"
14280
14281 order_2() {
14282         local value=$1
14283         local orig=$value
14284         local order=1
14285
14286         while [ $value -ge 2 ]; do
14287                 order=$((order*2))
14288                 value=$((value/2))
14289         done
14290
14291         if [ $orig -gt $order ]; then
14292                 order=$((order*2))
14293         fi
14294         echo $order
14295 }
14296
14297 size_in_KMGT() {
14298     local value=$1
14299     local size=('K' 'M' 'G' 'T');
14300     local i=0
14301     local size_string=$value
14302
14303     while [ $value -ge 1024 ]; do
14304         if [ $i -gt 3 ]; then
14305             #T is the biggest unit we get here, if that is bigger,
14306             #just return XXXT
14307             size_string=${value}T
14308             break
14309         fi
14310         value=$((value >> 10))
14311         if [ $value -lt 1024 ]; then
14312             size_string=${value}${size[$i]}
14313             break
14314         fi
14315         i=$((i + 1))
14316     done
14317
14318     echo $size_string
14319 }
14320
14321 get_rename_size() {
14322         local size=$1
14323         local context=${2:-.}
14324         local sample=$(do_facet $SINGLEMDS $LCTL \
14325                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14326                 grep -A1 $context |
14327                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14328         echo $sample
14329 }
14330
14331 test_133d() {
14332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14333         remote_ost_nodsh && skip "remote OST with nodsh"
14334         remote_mds_nodsh && skip "remote MDS with nodsh"
14335         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14336                 skip_env "MDS doesn't support rename stats"
14337
14338         local testdir1=$DIR/${tdir}/stats_testdir1
14339         local testdir2=$DIR/${tdir}/stats_testdir2
14340         mkdir -p $DIR/${tdir}
14341
14342         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14343
14344         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14345         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14346
14347         createmany -o $testdir1/test 512 || error "createmany failed"
14348
14349         # check samedir rename size
14350         mv ${testdir1}/test0 ${testdir1}/test_0
14351
14352         local testdir1_size=$(ls -l $DIR/${tdir} |
14353                 awk '/stats_testdir1/ {print $5}')
14354         local testdir2_size=$(ls -l $DIR/${tdir} |
14355                 awk '/stats_testdir2/ {print $5}')
14356
14357         testdir1_size=$(order_2 $testdir1_size)
14358         testdir2_size=$(order_2 $testdir2_size)
14359
14360         testdir1_size=$(size_in_KMGT $testdir1_size)
14361         testdir2_size=$(size_in_KMGT $testdir2_size)
14362
14363         echo "source rename dir size: ${testdir1_size}"
14364         echo "target rename dir size: ${testdir2_size}"
14365
14366         local cmd="do_facet $SINGLEMDS $LCTL "
14367         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14368
14369         eval $cmd || error "$cmd failed"
14370         local samedir=$($cmd | grep 'same_dir')
14371         local same_sample=$(get_rename_size $testdir1_size)
14372         [ -z "$samedir" ] && error "samedir_rename_size count error"
14373         [[ $same_sample -eq 1 ]] ||
14374                 error "samedir_rename_size error $same_sample"
14375         echo "Check same dir rename stats success"
14376
14377         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14378
14379         # check crossdir rename size
14380         mv ${testdir1}/test_0 ${testdir2}/test_0
14381
14382         testdir1_size=$(ls -l $DIR/${tdir} |
14383                 awk '/stats_testdir1/ {print $5}')
14384         testdir2_size=$(ls -l $DIR/${tdir} |
14385                 awk '/stats_testdir2/ {print $5}')
14386
14387         testdir1_size=$(order_2 $testdir1_size)
14388         testdir2_size=$(order_2 $testdir2_size)
14389
14390         testdir1_size=$(size_in_KMGT $testdir1_size)
14391         testdir2_size=$(size_in_KMGT $testdir2_size)
14392
14393         echo "source rename dir size: ${testdir1_size}"
14394         echo "target rename dir size: ${testdir2_size}"
14395
14396         eval $cmd || error "$cmd failed"
14397         local crossdir=$($cmd | grep 'crossdir')
14398         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14399         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14400         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14401         [[ $src_sample -eq 1 ]] ||
14402                 error "crossdir_rename_size error $src_sample"
14403         [[ $tgt_sample -eq 1 ]] ||
14404                 error "crossdir_rename_size error $tgt_sample"
14405         echo "Check cross dir rename stats success"
14406         rm -rf $DIR/${tdir}
14407 }
14408 run_test 133d "Verifying rename_stats ========================================"
14409
14410 test_133e() {
14411         remote_mds_nodsh && skip "remote MDS with nodsh"
14412         remote_ost_nodsh && skip "remote OST with nodsh"
14413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14414
14415         local testdir=$DIR/${tdir}/stats_testdir
14416         local ctr f0 f1 bs=32768 count=42 sum
14417
14418         mkdir -p ${testdir} || error "mkdir failed"
14419
14420         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14421
14422         for ctr in {write,read}_bytes; do
14423                 sync
14424                 cancel_lru_locks osc
14425
14426                 do_facet ost1 $LCTL set_param -n \
14427                         "obdfilter.*.exports.clear=clear"
14428
14429                 if [ $ctr = write_bytes ]; then
14430                         f0=/dev/zero
14431                         f1=${testdir}/${tfile}
14432                 else
14433                         f0=${testdir}/${tfile}
14434                         f1=/dev/null
14435                 fi
14436
14437                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14438                         error "dd failed"
14439                 sync
14440                 cancel_lru_locks osc
14441
14442                 sum=$(do_facet ost1 $LCTL get_param \
14443                         "obdfilter.*.exports.*.stats" |
14444                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14445                                 $1 == ctr { sum += $7 }
14446                                 END { printf("%0.0f", sum) }')
14447
14448                 if ((sum != bs * count)); then
14449                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14450                 fi
14451         done
14452
14453         rm -rf $DIR/${tdir}
14454 }
14455 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14456
14457 test_133f() {
14458         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14459                 skip "too old lustre for get_param -R ($facet_ver)"
14460
14461         # verifying readability.
14462         $LCTL get_param -R '*' &> /dev/null
14463
14464         # Verifing writability with badarea_io.
14465         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14466         local skipped_params='force_lbug|changelog_mask|daemon_file'
14467         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14468                 egrep -v "$skipped_params" |
14469                 xargs -n 1 find $proc_dirs -name |
14470                 xargs -n 1 badarea_io ||
14471                 error "client badarea_io failed"
14472
14473         # remount the FS in case writes/reads /proc break the FS
14474         cleanup || error "failed to unmount"
14475         setup || error "failed to setup"
14476 }
14477 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14478
14479 test_133g() {
14480         remote_mds_nodsh && skip "remote MDS with nodsh"
14481         remote_ost_nodsh && skip "remote OST with nodsh"
14482
14483         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14484         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14485         local facet
14486         for facet in mds1 ost1; do
14487                 local facet_ver=$(lustre_version_code $facet)
14488                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14489                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14490                 else
14491                         log "$facet: too old lustre for get_param -R"
14492                 fi
14493                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14494                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14495                                 tr -d = | egrep -v $skipped_params |
14496                                 xargs -n 1 find $proc_dirs -name |
14497                                 xargs -n 1 badarea_io" ||
14498                                         error "$facet badarea_io failed"
14499                 else
14500                         skip_noexit "$facet: too old lustre for get_param -R"
14501                 fi
14502         done
14503
14504         # remount the FS in case writes/reads /proc break the FS
14505         cleanup || error "failed to unmount"
14506         setup || error "failed to setup"
14507 }
14508 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14509
14510 test_133h() {
14511         remote_mds_nodsh && skip "remote MDS with nodsh"
14512         remote_ost_nodsh && skip "remote OST with nodsh"
14513         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14514                 skip "Need MDS version at least 2.9.54"
14515
14516         local facet
14517         for facet in client mds1 ost1; do
14518                 # Get the list of files that are missing the terminating newline
14519                 local plist=$(do_facet $facet
14520                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14521                 local ent
14522                 for ent in $plist; do
14523                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14524                                 awk -v FS='\v' -v RS='\v\v' \
14525                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14526                                         print FILENAME}'" 2>/dev/null)
14527                         [ -z $missing ] || {
14528                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14529                                 error "file does not end with newline: $facet-$ent"
14530                         }
14531                 done
14532         done
14533 }
14534 run_test 133h "Proc files should end with newlines"
14535
14536 test_134a() {
14537         remote_mds_nodsh && skip "remote MDS with nodsh"
14538         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14539                 skip "Need MDS version at least 2.7.54"
14540
14541         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14542         cancel_lru_locks mdc
14543
14544         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14545         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14546         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14547
14548         local nr=1000
14549         createmany -o $DIR/$tdir/f $nr ||
14550                 error "failed to create $nr files in $DIR/$tdir"
14551         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14552
14553         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14554         do_facet mds1 $LCTL set_param fail_loc=0x327
14555         do_facet mds1 $LCTL set_param fail_val=500
14556         touch $DIR/$tdir/m
14557
14558         echo "sleep 10 seconds ..."
14559         sleep 10
14560         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14561
14562         do_facet mds1 $LCTL set_param fail_loc=0
14563         do_facet mds1 $LCTL set_param fail_val=0
14564         [ $lck_cnt -lt $unused ] ||
14565                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14566
14567         rm $DIR/$tdir/m
14568         unlinkmany $DIR/$tdir/f $nr
14569 }
14570 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14571
14572 test_134b() {
14573         remote_mds_nodsh && skip "remote MDS with nodsh"
14574         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14575                 skip "Need MDS version at least 2.7.54"
14576
14577         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14578         cancel_lru_locks mdc
14579
14580         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14581                         ldlm.lock_reclaim_threshold_mb)
14582         # disable reclaim temporarily
14583         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14584
14585         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14586         do_facet mds1 $LCTL set_param fail_loc=0x328
14587         do_facet mds1 $LCTL set_param fail_val=500
14588
14589         $LCTL set_param debug=+trace
14590
14591         local nr=600
14592         createmany -o $DIR/$tdir/f $nr &
14593         local create_pid=$!
14594
14595         echo "Sleep $TIMEOUT seconds ..."
14596         sleep $TIMEOUT
14597         if ! ps -p $create_pid  > /dev/null 2>&1; then
14598                 do_facet mds1 $LCTL set_param fail_loc=0
14599                 do_facet mds1 $LCTL set_param fail_val=0
14600                 do_facet mds1 $LCTL set_param \
14601                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14602                 error "createmany finished incorrectly!"
14603         fi
14604         do_facet mds1 $LCTL set_param fail_loc=0
14605         do_facet mds1 $LCTL set_param fail_val=0
14606         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14607         wait $create_pid || return 1
14608
14609         unlinkmany $DIR/$tdir/f $nr
14610 }
14611 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14612
14613 test_135() {
14614         remote_mds_nodsh && skip "remote MDS with nodsh"
14615         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14616                 skip "Need MDS version at least 2.13.50"
14617         local fname
14618
14619         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14620
14621 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14622         #set only one record at plain llog
14623         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14624
14625         #fill already existed plain llog each 64767
14626         #wrapping whole catalog
14627         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14628
14629         createmany -o $DIR/$tdir/$tfile_ 64700
14630         for (( i = 0; i < 64700; i = i + 2 ))
14631         do
14632                 rm $DIR/$tdir/$tfile_$i &
14633                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14634                 local pid=$!
14635                 wait $pid
14636         done
14637
14638         #waiting osp synchronization
14639         wait_delete_completed
14640 }
14641 run_test 135 "Race catalog processing"
14642
14643 test_136() {
14644         remote_mds_nodsh && skip "remote MDS with nodsh"
14645         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14646                 skip "Need MDS version at least 2.13.50"
14647         local fname
14648
14649         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14650         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14651         #set only one record at plain llog
14652 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14653         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14654
14655         #fill already existed 2 plain llogs each 64767
14656         #wrapping whole catalog
14657         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14658         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14659         wait_delete_completed
14660
14661         createmany -o $DIR/$tdir/$tfile_ 10
14662         sleep 25
14663
14664         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14665         for (( i = 0; i < 10; i = i + 3 ))
14666         do
14667                 rm $DIR/$tdir/$tfile_$i &
14668                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14669                 local pid=$!
14670                 wait $pid
14671                 sleep 7
14672                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14673         done
14674
14675         #waiting osp synchronization
14676         wait_delete_completed
14677 }
14678 run_test 136 "Race catalog processing 2"
14679
14680 test_140() { #bug-17379
14681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14682
14683         test_mkdir $DIR/$tdir
14684         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14685         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14686
14687         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14688         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14689         local i=0
14690         while i=$((i + 1)); do
14691                 test_mkdir $i
14692                 cd $i || error "Changing to $i"
14693                 ln -s ../stat stat || error "Creating stat symlink"
14694                 # Read the symlink until ELOOP present,
14695                 # not LBUGing the system is considered success,
14696                 # we didn't overrun the stack.
14697                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14698                 if [ $ret -ne 0 ]; then
14699                         if [ $ret -eq 40 ]; then
14700                                 break  # -ELOOP
14701                         else
14702                                 error "Open stat symlink"
14703                                         return
14704                         fi
14705                 fi
14706         done
14707         i=$((i - 1))
14708         echo "The symlink depth = $i"
14709         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14710                 error "Invalid symlink depth"
14711
14712         # Test recursive symlink
14713         ln -s symlink_self symlink_self
14714         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14715         echo "open symlink_self returns $ret"
14716         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14717 }
14718 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14719
14720 test_150a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722
14723         local TF="$TMP/$tfile"
14724
14725         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14726         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14727         cp $TF $DIR/$tfile
14728         cancel_lru_locks $OSC
14729         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14730         remount_client $MOUNT
14731         df -P $MOUNT
14732         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14733
14734         $TRUNCATE $TF 6000
14735         $TRUNCATE $DIR/$tfile 6000
14736         cancel_lru_locks $OSC
14737         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14738
14739         echo "12345" >>$TF
14740         echo "12345" >>$DIR/$tfile
14741         cancel_lru_locks $OSC
14742         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14743
14744         echo "12345" >>$TF
14745         echo "12345" >>$DIR/$tfile
14746         cancel_lru_locks $OSC
14747         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14748 }
14749 run_test 150a "truncate/append tests"
14750
14751 test_150b() {
14752         check_set_fallocate_or_skip
14753
14754         touch $DIR/$tfile
14755         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14756         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14757 }
14758 run_test 150b "Verify fallocate (prealloc) functionality"
14759
14760 test_150bb() {
14761         check_set_fallocate_or_skip
14762
14763         touch $DIR/$tfile
14764         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14765         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14766         > $DIR/$tfile
14767         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14768         # precomputed md5sum for 20MB of zeroes
14769         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14770         local sum=($(md5sum $DIR/$tfile))
14771
14772         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14773
14774         check_set_fallocate 1
14775
14776         > $DIR/$tfile
14777         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14778         sum=($(md5sum $DIR/$tfile))
14779
14780         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14781 }
14782 run_test 150bb "Verify fallocate modes both zero space"
14783
14784 test_150c() {
14785         check_set_fallocate_or_skip
14786         local striping="-c2"
14787
14788         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14789         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14790         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14791         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14792         local want=$((OSTCOUNT * 1048576))
14793
14794         # Must allocate all requested space, not more than 5% extra
14795         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14796                 error "bytes $bytes is not $want"
14797
14798         rm -f $DIR/$tfile
14799
14800         echo "verify fallocate on PFL file"
14801
14802         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14803
14804         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14805                 error "Create $DIR/$tfile failed"
14806         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14807         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14808         want=$((512 * 1048576))
14809
14810         # Must allocate all requested space, not more than 5% extra
14811         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14812                 error "bytes $bytes is not $want"
14813 }
14814 run_test 150c "Verify fallocate Size and Blocks"
14815
14816 test_150d() {
14817         check_set_fallocate_or_skip
14818         local striping="-c2"
14819
14820         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14821
14822         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14823         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14824                 error "setstripe failed"
14825         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14826         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14827         local want=$((OSTCOUNT * 1048576))
14828
14829         # Must allocate all requested space, not more than 5% extra
14830         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14831                 error "bytes $bytes is not $want"
14832 }
14833 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14834
14835 test_150e() {
14836         check_set_fallocate_or_skip
14837
14838         echo "df before:"
14839         $LFS df
14840         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14841         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14842                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14843
14844         # Find OST with Minimum Size
14845         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14846                        sort -un | head -1)
14847
14848         # Get 100MB per OST of the available space to reduce run time
14849         # else 60% of the available space if we are running SLOW tests
14850         if [ $SLOW == "no" ]; then
14851                 local space=$((1024 * 100 * OSTCOUNT))
14852         else
14853                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14854         fi
14855
14856         fallocate -l${space}k $DIR/$tfile ||
14857                 error "fallocate ${space}k $DIR/$tfile failed"
14858         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14859
14860         # get size immediately after fallocate. This should be correctly
14861         # updated
14862         local size=$(stat -c '%s' $DIR/$tfile)
14863         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14864
14865         # Sleep for a while for statfs to get updated. And not pull from cache.
14866         sleep 2
14867
14868         echo "df after fallocate:"
14869         $LFS df
14870
14871         (( size / 1024 == space )) || error "size $size != requested $space"
14872         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14873                 error "used $used < space $space"
14874
14875         rm $DIR/$tfile || error "rm failed"
14876         sync
14877         wait_delete_completed
14878
14879         echo "df after unlink:"
14880         $LFS df
14881 }
14882 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14883
14884 test_150f() {
14885         local size
14886         local blocks
14887         local want_size_before=20480 # in bytes
14888         local want_blocks_before=40 # 512 sized blocks
14889         local want_blocks_after=24  # 512 sized blocks
14890         local length=$(((want_blocks_before - want_blocks_after) * 512))
14891
14892         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14893                 skip "need at least 2.14.0 for fallocate punch"
14894
14895         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14896                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14897         fi
14898
14899         check_set_fallocate_or_skip
14900         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14901
14902         [[ "x$DOM" == "xyes" ]] &&
14903                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14904
14905         echo "Verify fallocate punch: Range within the file range"
14906         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14907                 error "dd failed for bs 4096 and count 5"
14908
14909         # Call fallocate with punch range which is within the file range
14910         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14911                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14912         # client must see changes immediately after fallocate
14913         size=$(stat -c '%s' $DIR/$tfile)
14914         blocks=$(stat -c '%b' $DIR/$tfile)
14915
14916         # Verify punch worked.
14917         (( blocks == want_blocks_after )) ||
14918                 error "punch failed: blocks $blocks != $want_blocks_after"
14919
14920         (( size == want_size_before )) ||
14921                 error "punch failed: size $size != $want_size_before"
14922
14923         # Verify there is hole in file
14924         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14925         # precomputed md5sum
14926         local expect="4a9a834a2db02452929c0a348273b4aa"
14927
14928         cksum=($(md5sum $DIR/$tfile))
14929         [[ "${cksum[0]}" == "$expect" ]] ||
14930                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14931
14932         # Start second sub-case for fallocate punch.
14933         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14934         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14935                 error "dd failed for bs 4096 and count 5"
14936
14937         # Punch range less than block size will have no change in block count
14938         want_blocks_after=40  # 512 sized blocks
14939
14940         # Punch overlaps two blocks and less than blocksize
14941         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14942                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14943         size=$(stat -c '%s' $DIR/$tfile)
14944         blocks=$(stat -c '%b' $DIR/$tfile)
14945
14946         # Verify punch worked.
14947         (( blocks == want_blocks_after )) ||
14948                 error "punch failed: blocks $blocks != $want_blocks_after"
14949
14950         (( size == want_size_before )) ||
14951                 error "punch failed: size $size != $want_size_before"
14952
14953         # Verify if range is really zero'ed out. We expect Zeros.
14954         # precomputed md5sum
14955         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14956         cksum=($(md5sum $DIR/$tfile))
14957         [[ "${cksum[0]}" == "$expect" ]] ||
14958                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14959 }
14960 run_test 150f "Verify fallocate punch functionality"
14961
14962 test_150g() {
14963         local space
14964         local size
14965         local blocks
14966         local blocks_after
14967         local size_after
14968         local BS=4096 # Block size in bytes
14969
14970         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14971                 skip "need at least 2.14.0 for fallocate punch"
14972
14973         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14974                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14975         fi
14976
14977         check_set_fallocate_or_skip
14978         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14979
14980         if [[ "x$DOM" == "xyes" ]]; then
14981                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14982                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14983         else
14984                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14985                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14986         fi
14987
14988         # Get 100MB per OST of the available space to reduce run time
14989         # else 60% of the available space if we are running SLOW tests
14990         if [ $SLOW == "no" ]; then
14991                 space=$((1024 * 100 * OSTCOUNT))
14992         else
14993                 # Find OST with Minimum Size
14994                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14995                         sort -un | head -1)
14996                 echo "min size OST: $space"
14997                 space=$(((space * 60)/100 * OSTCOUNT))
14998         fi
14999         # space in 1k units, round to 4k blocks
15000         local blkcount=$((space * 1024 / $BS))
15001
15002         echo "Verify fallocate punch: Very large Range"
15003         fallocate -l${space}k $DIR/$tfile ||
15004                 error "fallocate ${space}k $DIR/$tfile failed"
15005         # write 1M at the end, start and in the middle
15006         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15007                 error "dd failed: bs $BS count 256"
15008         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15009                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15010         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15011                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15012
15013         # Gather stats.
15014         size=$(stat -c '%s' $DIR/$tfile)
15015
15016         # gather punch length.
15017         local punch_size=$((size - (BS * 2)))
15018
15019         echo "punch_size = $punch_size"
15020         echo "size - punch_size: $((size - punch_size))"
15021         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15022
15023         # Call fallocate to punch all except 2 blocks. We leave the
15024         # first and the last block
15025         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15026         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15027                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15028
15029         size_after=$(stat -c '%s' $DIR/$tfile)
15030         blocks_after=$(stat -c '%b' $DIR/$tfile)
15031
15032         # Verify punch worked.
15033         # Size should be kept
15034         (( size == size_after )) ||
15035                 error "punch failed: size $size != $size_after"
15036
15037         # two 4k data blocks to remain plus possible 1 extra extent block
15038         (( blocks_after <= ((BS / 512) * 3) )) ||
15039                 error "too many blocks remains: $blocks_after"
15040
15041         # Verify that file has hole between the first and the last blocks
15042         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15043         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15044
15045         echo "Hole at [$hole_start, $hole_end)"
15046         (( hole_start == BS )) ||
15047                 error "no hole at offset $BS after punch"
15048
15049         (( hole_end == BS + punch_size )) ||
15050                 error "data at offset $hole_end < $((BS + punch_size))"
15051 }
15052 run_test 150g "Verify fallocate punch on large range"
15053
15054 #LU-2902 roc_hit was not able to read all values from lproc
15055 function roc_hit_init() {
15056         local list=$(comma_list $(osts_nodes))
15057         local dir=$DIR/$tdir-check
15058         local file=$dir/$tfile
15059         local BEFORE
15060         local AFTER
15061         local idx
15062
15063         test_mkdir $dir
15064         #use setstripe to do a write to every ost
15065         for i in $(seq 0 $((OSTCOUNT-1))); do
15066                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15067                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15068                 idx=$(printf %04x $i)
15069                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15070                         awk '$1 == "cache_access" {sum += $7}
15071                                 END { printf("%0.0f", sum) }')
15072
15073                 cancel_lru_locks osc
15074                 cat $file >/dev/null
15075
15076                 AFTER=$(get_osd_param $list *OST*$idx stats |
15077                         awk '$1 == "cache_access" {sum += $7}
15078                                 END { printf("%0.0f", sum) }')
15079
15080                 echo BEFORE:$BEFORE AFTER:$AFTER
15081                 if ! let "AFTER - BEFORE == 4"; then
15082                         rm -rf $dir
15083                         error "roc_hit is not safe to use"
15084                 fi
15085                 rm $file
15086         done
15087
15088         rm -rf $dir
15089 }
15090
15091 function roc_hit() {
15092         local list=$(comma_list $(osts_nodes))
15093         echo $(get_osd_param $list '' stats |
15094                 awk '$1 == "cache_hit" {sum += $7}
15095                         END { printf("%0.0f", sum) }')
15096 }
15097
15098 function set_cache() {
15099         local on=1
15100
15101         if [ "$2" == "off" ]; then
15102                 on=0;
15103         fi
15104         local list=$(comma_list $(osts_nodes))
15105         set_osd_param $list '' $1_cache_enable $on
15106
15107         cancel_lru_locks osc
15108 }
15109
15110 test_151() {
15111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15112         remote_ost_nodsh && skip "remote OST with nodsh"
15113
15114         local CPAGES=3
15115         local list=$(comma_list $(osts_nodes))
15116
15117         # check whether obdfilter is cache capable at all
15118         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15119                 skip "not cache-capable obdfilter"
15120         fi
15121
15122         # check cache is enabled on all obdfilters
15123         if get_osd_param $list '' read_cache_enable | grep 0; then
15124                 skip "oss cache is disabled"
15125         fi
15126
15127         set_osd_param $list '' writethrough_cache_enable 1
15128
15129         # check write cache is enabled on all obdfilters
15130         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15131                 skip "oss write cache is NOT enabled"
15132         fi
15133
15134         roc_hit_init
15135
15136         #define OBD_FAIL_OBD_NO_LRU  0x609
15137         do_nodes $list $LCTL set_param fail_loc=0x609
15138
15139         # pages should be in the case right after write
15140         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15141                 error "dd failed"
15142
15143         local BEFORE=$(roc_hit)
15144         cancel_lru_locks osc
15145         cat $DIR/$tfile >/dev/null
15146         local AFTER=$(roc_hit)
15147
15148         do_nodes $list $LCTL set_param fail_loc=0
15149
15150         if ! let "AFTER - BEFORE == CPAGES"; then
15151                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15152         fi
15153
15154         cancel_lru_locks osc
15155         # invalidates OST cache
15156         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15157         set_osd_param $list '' read_cache_enable 0
15158         cat $DIR/$tfile >/dev/null
15159
15160         # now data shouldn't be found in the cache
15161         BEFORE=$(roc_hit)
15162         cancel_lru_locks osc
15163         cat $DIR/$tfile >/dev/null
15164         AFTER=$(roc_hit)
15165         if let "AFTER - BEFORE != 0"; then
15166                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15167         fi
15168
15169         set_osd_param $list '' read_cache_enable 1
15170         rm -f $DIR/$tfile
15171 }
15172 run_test 151 "test cache on oss and controls ==============================="
15173
15174 test_152() {
15175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15176
15177         local TF="$TMP/$tfile"
15178
15179         # simulate ENOMEM during write
15180 #define OBD_FAIL_OST_NOMEM      0x226
15181         lctl set_param fail_loc=0x80000226
15182         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15183         cp $TF $DIR/$tfile
15184         sync || error "sync failed"
15185         lctl set_param fail_loc=0
15186
15187         # discard client's cache
15188         cancel_lru_locks osc
15189
15190         # simulate ENOMEM during read
15191         lctl set_param fail_loc=0x80000226
15192         cmp $TF $DIR/$tfile || error "cmp failed"
15193         lctl set_param fail_loc=0
15194
15195         rm -f $TF
15196 }
15197 run_test 152 "test read/write with enomem ============================"
15198
15199 test_153() {
15200         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15201 }
15202 run_test 153 "test if fdatasync does not crash ======================="
15203
15204 dot_lustre_fid_permission_check() {
15205         local fid=$1
15206         local ffid=$MOUNT/.lustre/fid/$fid
15207         local test_dir=$2
15208
15209         echo "stat fid $fid"
15210         stat $ffid > /dev/null || error "stat $ffid failed."
15211         echo "touch fid $fid"
15212         touch $ffid || error "touch $ffid failed."
15213         echo "write to fid $fid"
15214         cat /etc/hosts > $ffid || error "write $ffid failed."
15215         echo "read fid $fid"
15216         diff /etc/hosts $ffid || error "read $ffid failed."
15217         echo "append write to fid $fid"
15218         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15219         echo "rename fid $fid"
15220         mv $ffid $test_dir/$tfile.1 &&
15221                 error "rename $ffid to $tfile.1 should fail."
15222         touch $test_dir/$tfile.1
15223         mv $test_dir/$tfile.1 $ffid &&
15224                 error "rename $tfile.1 to $ffid should fail."
15225         rm -f $test_dir/$tfile.1
15226         echo "truncate fid $fid"
15227         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15228         echo "link fid $fid"
15229         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15230         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15231                 echo "setfacl fid $fid"
15232                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15233                 echo "getfacl fid $fid"
15234                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15235         fi
15236         echo "unlink fid $fid"
15237         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15238         echo "mknod fid $fid"
15239         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15240
15241         fid=[0xf00000400:0x1:0x0]
15242         ffid=$MOUNT/.lustre/fid/$fid
15243
15244         echo "stat non-exist fid $fid"
15245         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15246         echo "write to non-exist fid $fid"
15247         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15248         echo "link new fid $fid"
15249         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15250
15251         mkdir -p $test_dir/$tdir
15252         touch $test_dir/$tdir/$tfile
15253         fid=$($LFS path2fid $test_dir/$tdir)
15254         rc=$?
15255         [ $rc -ne 0 ] &&
15256                 error "error: could not get fid for $test_dir/$dir/$tfile."
15257
15258         ffid=$MOUNT/.lustre/fid/$fid
15259
15260         echo "ls $fid"
15261         ls $ffid > /dev/null || error "ls $ffid failed."
15262         echo "touch $fid/$tfile.1"
15263         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15264
15265         echo "touch $MOUNT/.lustre/fid/$tfile"
15266         touch $MOUNT/.lustre/fid/$tfile && \
15267                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15268
15269         echo "setxattr to $MOUNT/.lustre/fid"
15270         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15271
15272         echo "listxattr for $MOUNT/.lustre/fid"
15273         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15274
15275         echo "delxattr from $MOUNT/.lustre/fid"
15276         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15277
15278         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15279         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15280                 error "touch invalid fid should fail."
15281
15282         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15283         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15284                 error "touch non-normal fid should fail."
15285
15286         echo "rename $tdir to $MOUNT/.lustre/fid"
15287         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15288                 error "rename to $MOUNT/.lustre/fid should fail."
15289
15290         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15291         then            # LU-3547
15292                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15293                 local new_obf_mode=777
15294
15295                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15296                 chmod $new_obf_mode $DIR/.lustre/fid ||
15297                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15298
15299                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15300                 [ $obf_mode -eq $new_obf_mode ] ||
15301                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15302
15303                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15304                 chmod $old_obf_mode $DIR/.lustre/fid ||
15305                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15306         fi
15307
15308         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15309         fid=$($LFS path2fid $test_dir/$tfile-2)
15310
15311         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15312         then # LU-5424
15313                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15314                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15315                         error "create lov data thru .lustre failed"
15316         fi
15317         echo "cp /etc/passwd $test_dir/$tfile-2"
15318         cp /etc/passwd $test_dir/$tfile-2 ||
15319                 error "copy to $test_dir/$tfile-2 failed."
15320         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15321         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15322                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15323
15324         rm -rf $test_dir/tfile.lnk
15325         rm -rf $test_dir/$tfile-2
15326 }
15327
15328 test_154A() {
15329         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15330                 skip "Need MDS version at least 2.4.1"
15331
15332         local tf=$DIR/$tfile
15333         touch $tf
15334
15335         local fid=$($LFS path2fid $tf)
15336         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15337
15338         # check that we get the same pathname back
15339         local rootpath
15340         local found
15341         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15342                 echo "$rootpath $fid"
15343                 found=$($LFS fid2path $rootpath "$fid")
15344                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15345                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15346         done
15347
15348         # check wrong root path format
15349         rootpath=$MOUNT"_wrong"
15350         found=$($LFS fid2path $rootpath "$fid")
15351         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15352 }
15353 run_test 154A "lfs path2fid and fid2path basic checks"
15354
15355 test_154B() {
15356         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15357                 skip "Need MDS version at least 2.4.1"
15358
15359         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15360         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15361         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15362         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15363
15364         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15365         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15366
15367         # check that we get the same pathname
15368         echo "PFID: $PFID, name: $name"
15369         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15370         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15371         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15372                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15373
15374         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15375 }
15376 run_test 154B "verify the ll_decode_linkea tool"
15377
15378 test_154a() {
15379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15380         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15381         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15382                 skip "Need MDS version at least 2.2.51"
15383         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15384
15385         cp /etc/hosts $DIR/$tfile
15386
15387         fid=$($LFS path2fid $DIR/$tfile)
15388         rc=$?
15389         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15390
15391         dot_lustre_fid_permission_check "$fid" $DIR ||
15392                 error "dot lustre permission check $fid failed"
15393
15394         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15395
15396         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15397
15398         touch $MOUNT/.lustre/file &&
15399                 error "creation is not allowed under .lustre"
15400
15401         mkdir $MOUNT/.lustre/dir &&
15402                 error "mkdir is not allowed under .lustre"
15403
15404         rm -rf $DIR/$tfile
15405 }
15406 run_test 154a "Open-by-FID"
15407
15408 test_154b() {
15409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15410         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15411         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15412         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15413                 skip "Need MDS version at least 2.2.51"
15414
15415         local remote_dir=$DIR/$tdir/remote_dir
15416         local MDTIDX=1
15417         local rc=0
15418
15419         mkdir -p $DIR/$tdir
15420         $LFS mkdir -i $MDTIDX $remote_dir ||
15421                 error "create remote directory failed"
15422
15423         cp /etc/hosts $remote_dir/$tfile
15424
15425         fid=$($LFS path2fid $remote_dir/$tfile)
15426         rc=$?
15427         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15428
15429         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15430                 error "dot lustre permission check $fid failed"
15431         rm -rf $DIR/$tdir
15432 }
15433 run_test 154b "Open-by-FID for remote directory"
15434
15435 test_154c() {
15436         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15437                 skip "Need MDS version at least 2.4.1"
15438
15439         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15440         local FID1=$($LFS path2fid $DIR/$tfile.1)
15441         local FID2=$($LFS path2fid $DIR/$tfile.2)
15442         local FID3=$($LFS path2fid $DIR/$tfile.3)
15443
15444         local N=1
15445         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15446                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15447                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15448                 local want=FID$N
15449                 [ "$FID" = "${!want}" ] ||
15450                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15451                 N=$((N + 1))
15452         done
15453
15454         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15455         do
15456                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15457                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15458                 N=$((N + 1))
15459         done
15460 }
15461 run_test 154c "lfs path2fid and fid2path multiple arguments"
15462
15463 test_154d() {
15464         remote_mds_nodsh && skip "remote MDS with nodsh"
15465         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15466                 skip "Need MDS version at least 2.5.53"
15467
15468         if remote_mds; then
15469                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15470         else
15471                 nid="0@lo"
15472         fi
15473         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15474         local fd
15475         local cmd
15476
15477         rm -f $DIR/$tfile
15478         touch $DIR/$tfile
15479
15480         local fid=$($LFS path2fid $DIR/$tfile)
15481         # Open the file
15482         fd=$(free_fd)
15483         cmd="exec $fd<$DIR/$tfile"
15484         eval $cmd
15485         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15486         echo "$fid_list" | grep "$fid"
15487         rc=$?
15488
15489         cmd="exec $fd>/dev/null"
15490         eval $cmd
15491         if [ $rc -ne 0 ]; then
15492                 error "FID $fid not found in open files list $fid_list"
15493         fi
15494 }
15495 run_test 154d "Verify open file fid"
15496
15497 test_154e()
15498 {
15499         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15500                 skip "Need MDS version at least 2.6.50"
15501
15502         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15503                 error ".lustre returned by readdir"
15504         fi
15505 }
15506 run_test 154e ".lustre is not returned by readdir"
15507
15508 test_154f() {
15509         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15510
15511         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15512         mkdir_on_mdt0 $DIR/$tdir
15513         # test dirs inherit from its stripe
15514         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15515         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15516         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15517         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15518         touch $DIR/f
15519
15520         # get fid of parents
15521         local FID0=$($LFS path2fid $DIR/$tdir)
15522         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15523         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15524         local FID3=$($LFS path2fid $DIR)
15525
15526         # check that path2fid --parents returns expected <parent_fid>/name
15527         # 1) test for a directory (single parent)
15528         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15529         [ "$parent" == "$FID0/foo1" ] ||
15530                 error "expected parent: $FID0/foo1, got: $parent"
15531
15532         # 2) test for a file with nlink > 1 (multiple parents)
15533         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15534         echo "$parent" | grep -F "$FID1/$tfile" ||
15535                 error "$FID1/$tfile not returned in parent list"
15536         echo "$parent" | grep -F "$FID2/link" ||
15537                 error "$FID2/link not returned in parent list"
15538
15539         # 3) get parent by fid
15540         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15541         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15542         echo "$parent" | grep -F "$FID1/$tfile" ||
15543                 error "$FID1/$tfile not returned in parent list (by fid)"
15544         echo "$parent" | grep -F "$FID2/link" ||
15545                 error "$FID2/link not returned in parent list (by fid)"
15546
15547         # 4) test for entry in root directory
15548         parent=$($LFS path2fid --parents $DIR/f)
15549         echo "$parent" | grep -F "$FID3/f" ||
15550                 error "$FID3/f not returned in parent list"
15551
15552         # 5) test it on root directory
15553         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15554                 error "$MOUNT should not have parents"
15555
15556         # enable xattr caching and check that linkea is correctly updated
15557         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15558         save_lustre_params client "llite.*.xattr_cache" > $save
15559         lctl set_param llite.*.xattr_cache 1
15560
15561         # 6.1) linkea update on rename
15562         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15563
15564         # get parents by fid
15565         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15566         # foo1 should no longer be returned in parent list
15567         echo "$parent" | grep -F "$FID1" &&
15568                 error "$FID1 should no longer be in parent list"
15569         # the new path should appear
15570         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15571                 error "$FID2/$tfile.moved is not in parent list"
15572
15573         # 6.2) linkea update on unlink
15574         rm -f $DIR/$tdir/foo2/link
15575         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15576         # foo2/link should no longer be returned in parent list
15577         echo "$parent" | grep -F "$FID2/link" &&
15578                 error "$FID2/link should no longer be in parent list"
15579         true
15580
15581         rm -f $DIR/f
15582         restore_lustre_params < $save
15583         rm -f $save
15584 }
15585 run_test 154f "get parent fids by reading link ea"
15586
15587 test_154g()
15588 {
15589         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15590         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15591            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15592                 skip "Need MDS version at least 2.6.92"
15593
15594         mkdir_on_mdt0 $DIR/$tdir
15595         llapi_fid_test -d $DIR/$tdir
15596 }
15597 run_test 154g "various llapi FID tests"
15598
15599 test_155_small_load() {
15600     local temp=$TMP/$tfile
15601     local file=$DIR/$tfile
15602
15603     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15604         error "dd of=$temp bs=6096 count=1 failed"
15605     cp $temp $file
15606     cancel_lru_locks $OSC
15607     cmp $temp $file || error "$temp $file differ"
15608
15609     $TRUNCATE $temp 6000
15610     $TRUNCATE $file 6000
15611     cmp $temp $file || error "$temp $file differ (truncate1)"
15612
15613     echo "12345" >>$temp
15614     echo "12345" >>$file
15615     cmp $temp $file || error "$temp $file differ (append1)"
15616
15617     echo "12345" >>$temp
15618     echo "12345" >>$file
15619     cmp $temp $file || error "$temp $file differ (append2)"
15620
15621     rm -f $temp $file
15622     true
15623 }
15624
15625 test_155_big_load() {
15626         remote_ost_nodsh && skip "remote OST with nodsh"
15627
15628         local temp=$TMP/$tfile
15629         local file=$DIR/$tfile
15630
15631         free_min_max
15632         local cache_size=$(do_facet ost$((MAXI+1)) \
15633                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15634         local large_file_size=$((cache_size * 2))
15635
15636         echo "OSS cache size: $cache_size KB"
15637         echo "Large file size: $large_file_size KB"
15638
15639         [ $MAXV -le $large_file_size ] &&
15640                 skip_env "max available OST size needs > $large_file_size KB"
15641
15642         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15643
15644         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15645                 error "dd of=$temp bs=$large_file_size count=1k failed"
15646         cp $temp $file
15647         ls -lh $temp $file
15648         cancel_lru_locks osc
15649         cmp $temp $file || error "$temp $file differ"
15650
15651         rm -f $temp $file
15652         true
15653 }
15654
15655 save_writethrough() {
15656         local facets=$(get_facets OST)
15657
15658         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15659 }
15660
15661 test_155a() {
15662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15663
15664         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15665
15666         save_writethrough $p
15667
15668         set_cache read on
15669         set_cache writethrough on
15670         test_155_small_load
15671         restore_lustre_params < $p
15672         rm -f $p
15673 }
15674 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15675
15676 test_155b() {
15677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15678
15679         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15680
15681         save_writethrough $p
15682
15683         set_cache read on
15684         set_cache writethrough off
15685         test_155_small_load
15686         restore_lustre_params < $p
15687         rm -f $p
15688 }
15689 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15690
15691 test_155c() {
15692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15693
15694         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15695
15696         save_writethrough $p
15697
15698         set_cache read off
15699         set_cache writethrough on
15700         test_155_small_load
15701         restore_lustre_params < $p
15702         rm -f $p
15703 }
15704 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15705
15706 test_155d() {
15707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15708
15709         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15710
15711         save_writethrough $p
15712
15713         set_cache read off
15714         set_cache writethrough off
15715         test_155_small_load
15716         restore_lustre_params < $p
15717         rm -f $p
15718 }
15719 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15720
15721 test_155e() {
15722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15723
15724         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15725
15726         save_writethrough $p
15727
15728         set_cache read on
15729         set_cache writethrough on
15730         test_155_big_load
15731         restore_lustre_params < $p
15732         rm -f $p
15733 }
15734 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15735
15736 test_155f() {
15737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15738
15739         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15740
15741         save_writethrough $p
15742
15743         set_cache read on
15744         set_cache writethrough off
15745         test_155_big_load
15746         restore_lustre_params < $p
15747         rm -f $p
15748 }
15749 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15750
15751 test_155g() {
15752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15753
15754         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15755
15756         save_writethrough $p
15757
15758         set_cache read off
15759         set_cache writethrough on
15760         test_155_big_load
15761         restore_lustre_params < $p
15762         rm -f $p
15763 }
15764 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15765
15766 test_155h() {
15767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15768
15769         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15770
15771         save_writethrough $p
15772
15773         set_cache read off
15774         set_cache writethrough off
15775         test_155_big_load
15776         restore_lustre_params < $p
15777         rm -f $p
15778 }
15779 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15780
15781 test_156() {
15782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15783         remote_ost_nodsh && skip "remote OST with nodsh"
15784         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15785                 skip "stats not implemented on old servers"
15786         [ "$ost1_FSTYPE" = "zfs" ] &&
15787                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15788
15789         local CPAGES=3
15790         local BEFORE
15791         local AFTER
15792         local file="$DIR/$tfile"
15793         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15794
15795         save_writethrough $p
15796         roc_hit_init
15797
15798         log "Turn on read and write cache"
15799         set_cache read on
15800         set_cache writethrough on
15801
15802         log "Write data and read it back."
15803         log "Read should be satisfied from the cache."
15804         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15805         BEFORE=$(roc_hit)
15806         cancel_lru_locks osc
15807         cat $file >/dev/null
15808         AFTER=$(roc_hit)
15809         if ! let "AFTER - BEFORE == CPAGES"; then
15810                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15811         else
15812                 log "cache hits: before: $BEFORE, after: $AFTER"
15813         fi
15814
15815         log "Read again; it should be satisfied from the cache."
15816         BEFORE=$AFTER
15817         cancel_lru_locks osc
15818         cat $file >/dev/null
15819         AFTER=$(roc_hit)
15820         if ! let "AFTER - BEFORE == CPAGES"; then
15821                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15822         else
15823                 log "cache hits:: before: $BEFORE, after: $AFTER"
15824         fi
15825
15826         log "Turn off the read cache and turn on the write cache"
15827         set_cache read off
15828         set_cache writethrough on
15829
15830         log "Read again; it should be satisfied from the cache."
15831         BEFORE=$(roc_hit)
15832         cancel_lru_locks osc
15833         cat $file >/dev/null
15834         AFTER=$(roc_hit)
15835         if ! let "AFTER - BEFORE == CPAGES"; then
15836                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15837         else
15838                 log "cache hits:: before: $BEFORE, after: $AFTER"
15839         fi
15840
15841         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15842                 # > 2.12.56 uses pagecache if cached
15843                 log "Read again; it should not be satisfied from the cache."
15844                 BEFORE=$AFTER
15845                 cancel_lru_locks osc
15846                 cat $file >/dev/null
15847                 AFTER=$(roc_hit)
15848                 if ! let "AFTER - BEFORE == 0"; then
15849                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15850                 else
15851                         log "cache hits:: before: $BEFORE, after: $AFTER"
15852                 fi
15853         fi
15854
15855         log "Write data and read it back."
15856         log "Read should be satisfied from the cache."
15857         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15858         BEFORE=$(roc_hit)
15859         cancel_lru_locks osc
15860         cat $file >/dev/null
15861         AFTER=$(roc_hit)
15862         if ! let "AFTER - BEFORE == CPAGES"; then
15863                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15864         else
15865                 log "cache hits:: before: $BEFORE, after: $AFTER"
15866         fi
15867
15868         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15869                 # > 2.12.56 uses pagecache if cached
15870                 log "Read again; it should not be satisfied from the cache."
15871                 BEFORE=$AFTER
15872                 cancel_lru_locks osc
15873                 cat $file >/dev/null
15874                 AFTER=$(roc_hit)
15875                 if ! let "AFTER - BEFORE == 0"; then
15876                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15877                 else
15878                         log "cache hits:: before: $BEFORE, after: $AFTER"
15879                 fi
15880         fi
15881
15882         log "Turn off read and write cache"
15883         set_cache read off
15884         set_cache writethrough off
15885
15886         log "Write data and read it back"
15887         log "It should not be satisfied from the cache."
15888         rm -f $file
15889         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15890         cancel_lru_locks osc
15891         BEFORE=$(roc_hit)
15892         cat $file >/dev/null
15893         AFTER=$(roc_hit)
15894         if ! let "AFTER - BEFORE == 0"; then
15895                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15896         else
15897                 log "cache hits:: before: $BEFORE, after: $AFTER"
15898         fi
15899
15900         log "Turn on the read cache and turn off the write cache"
15901         set_cache read on
15902         set_cache writethrough off
15903
15904         log "Write data and read it back"
15905         log "It should not be satisfied from the cache."
15906         rm -f $file
15907         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15908         BEFORE=$(roc_hit)
15909         cancel_lru_locks osc
15910         cat $file >/dev/null
15911         AFTER=$(roc_hit)
15912         if ! let "AFTER - BEFORE == 0"; then
15913                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15914         else
15915                 log "cache hits:: before: $BEFORE, after: $AFTER"
15916         fi
15917
15918         log "Read again; it should be satisfied from the cache."
15919         BEFORE=$(roc_hit)
15920         cancel_lru_locks osc
15921         cat $file >/dev/null
15922         AFTER=$(roc_hit)
15923         if ! let "AFTER - BEFORE == CPAGES"; then
15924                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15925         else
15926                 log "cache hits:: before: $BEFORE, after: $AFTER"
15927         fi
15928
15929         restore_lustre_params < $p
15930         rm -f $p $file
15931 }
15932 run_test 156 "Verification of tunables"
15933
15934 test_160a() {
15935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15936         remote_mds_nodsh && skip "remote MDS with nodsh"
15937         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15938                 skip "Need MDS version at least 2.2.0"
15939
15940         changelog_register || error "changelog_register failed"
15941         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15942         changelog_users $SINGLEMDS | grep -q $cl_user ||
15943                 error "User $cl_user not found in changelog_users"
15944
15945         mkdir_on_mdt0 $DIR/$tdir
15946
15947         # change something
15948         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15949         changelog_clear 0 || error "changelog_clear failed"
15950         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15951         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15952         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15953         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15954         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15955         rm $DIR/$tdir/pics/desktop.jpg
15956
15957         echo "verifying changelog mask"
15958         changelog_chmask "-MKDIR"
15959         changelog_chmask "-CLOSE"
15960
15961         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15962         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15963
15964         changelog_chmask "+MKDIR"
15965         changelog_chmask "+CLOSE"
15966
15967         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15968         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15969
15970         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15971         CLOSES=$(changelog_dump | grep -c "CLOSE")
15972         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15973         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15974
15975         # verify contents
15976         echo "verifying target fid"
15977         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15978         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15979         [ "$fidc" == "$fidf" ] ||
15980                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15981         echo "verifying parent fid"
15982         # The FID returned from the Changelog may be the directory shard on
15983         # a different MDT, and not the FID returned by path2fid on the parent.
15984         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15985         # since this is what will matter when recreating this file in the tree.
15986         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15987         local pathp=$($LFS fid2path $MOUNT "$fidp")
15988         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15989                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15990
15991         echo "getting records for $cl_user"
15992         changelog_users $SINGLEMDS
15993         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15994         local nclr=3
15995         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15996                 error "changelog_clear failed"
15997         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15998         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15999         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16000                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16001
16002         local min0_rec=$(changelog_users $SINGLEMDS |
16003                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16004         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16005                           awk '{ print $1; exit; }')
16006
16007         changelog_dump | tail -n 5
16008         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16009         [ $first_rec == $((min0_rec + 1)) ] ||
16010                 error "first index should be $min0_rec + 1 not $first_rec"
16011
16012         # LU-3446 changelog index reset on MDT restart
16013         local cur_rec1=$(changelog_users $SINGLEMDS |
16014                          awk '/^current.index:/ { print $NF }')
16015         changelog_clear 0 ||
16016                 error "clear all changelog records for $cl_user failed"
16017         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16018         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16019                 error "Fail to start $SINGLEMDS"
16020         local cur_rec2=$(changelog_users $SINGLEMDS |
16021                          awk '/^current.index:/ { print $NF }')
16022         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16023         [ $cur_rec1 == $cur_rec2 ] ||
16024                 error "current index should be $cur_rec1 not $cur_rec2"
16025
16026         echo "verifying users from this test are deregistered"
16027         changelog_deregister || error "changelog_deregister failed"
16028         changelog_users $SINGLEMDS | grep -q $cl_user &&
16029                 error "User '$cl_user' still in changelog_users"
16030
16031         # lctl get_param -n mdd.*.changelog_users
16032         # current_index: 144
16033         # ID    index (idle seconds)
16034         # cl3   144   (2) mask=<list>
16035         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16036                 # this is the normal case where all users were deregistered
16037                 # make sure no new records are added when no users are present
16038                 local last_rec1=$(changelog_users $SINGLEMDS |
16039                                   awk '/^current.index:/ { print $NF }')
16040                 touch $DIR/$tdir/chloe
16041                 local last_rec2=$(changelog_users $SINGLEMDS |
16042                                   awk '/^current.index:/ { print $NF }')
16043                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16044                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16045         else
16046                 # any changelog users must be leftovers from a previous test
16047                 changelog_users $SINGLEMDS
16048                 echo "other changelog users; can't verify off"
16049         fi
16050 }
16051 run_test 160a "changelog sanity"
16052
16053 test_160b() { # LU-3587
16054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16055         remote_mds_nodsh && skip "remote MDS with nodsh"
16056         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16057                 skip "Need MDS version at least 2.2.0"
16058
16059         changelog_register || error "changelog_register failed"
16060         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16061         changelog_users $SINGLEMDS | grep -q $cl_user ||
16062                 error "User '$cl_user' not found in changelog_users"
16063
16064         local longname1=$(str_repeat a 255)
16065         local longname2=$(str_repeat b 255)
16066
16067         cd $DIR
16068         echo "creating very long named file"
16069         touch $longname1 || error "create of '$longname1' failed"
16070         echo "renaming very long named file"
16071         mv $longname1 $longname2
16072
16073         changelog_dump | grep RENME | tail -n 5
16074         rm -f $longname2
16075 }
16076 run_test 160b "Verify that very long rename doesn't crash in changelog"
16077
16078 test_160c() {
16079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16080         remote_mds_nodsh && skip "remote MDS with nodsh"
16081
16082         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16083                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16084                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16085                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16086
16087         local rc=0
16088
16089         # Registration step
16090         changelog_register || error "changelog_register failed"
16091
16092         rm -rf $DIR/$tdir
16093         mkdir -p $DIR/$tdir
16094         $MCREATE $DIR/$tdir/foo_160c
16095         changelog_chmask "-TRUNC"
16096         $TRUNCATE $DIR/$tdir/foo_160c 200
16097         changelog_chmask "+TRUNC"
16098         $TRUNCATE $DIR/$tdir/foo_160c 199
16099         changelog_dump | tail -n 5
16100         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16101         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16102 }
16103 run_test 160c "verify that changelog log catch the truncate event"
16104
16105 test_160d() {
16106         remote_mds_nodsh && skip "remote MDS with nodsh"
16107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16109         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16110                 skip "Need MDS version at least 2.7.60"
16111
16112         # Registration step
16113         changelog_register || error "changelog_register failed"
16114
16115         mkdir -p $DIR/$tdir/migrate_dir
16116         changelog_clear 0 || error "changelog_clear failed"
16117
16118         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16119         changelog_dump | tail -n 5
16120         local migrates=$(changelog_dump | grep -c "MIGRT")
16121         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16122 }
16123 run_test 160d "verify that changelog log catch the migrate event"
16124
16125 test_160e() {
16126         remote_mds_nodsh && skip "remote MDS with nodsh"
16127
16128         # Create a user
16129         changelog_register || error "changelog_register failed"
16130
16131         local MDT0=$(facet_svc $SINGLEMDS)
16132         local rc
16133
16134         # No user (expect fail)
16135         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16136         rc=$?
16137         if [ $rc -eq 0 ]; then
16138                 error "Should fail without user"
16139         elif [ $rc -ne 4 ]; then
16140                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16141         fi
16142
16143         # Delete a future user (expect fail)
16144         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16145         rc=$?
16146         if [ $rc -eq 0 ]; then
16147                 error "Deleted non-existant user cl77"
16148         elif [ $rc -ne 2 ]; then
16149                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16150         fi
16151
16152         # Clear to a bad index (1 billion should be safe)
16153         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16154         rc=$?
16155
16156         if [ $rc -eq 0 ]; then
16157                 error "Successfully cleared to invalid CL index"
16158         elif [ $rc -ne 22 ]; then
16159                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16160         fi
16161 }
16162 run_test 160e "changelog negative testing (should return errors)"
16163
16164 test_160f() {
16165         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16166         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16167                 skip "Need MDS version at least 2.10.56"
16168
16169         local mdts=$(comma_list $(mdts_nodes))
16170
16171         # Create a user
16172         changelog_register || error "first changelog_register failed"
16173         changelog_register || error "second changelog_register failed"
16174         local cl_users
16175         declare -A cl_user1
16176         declare -A cl_user2
16177         local user_rec1
16178         local user_rec2
16179         local i
16180
16181         # generate some changelog records to accumulate on each MDT
16182         # use all_char because created files should be evenly distributed
16183         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16184                 error "test_mkdir $tdir failed"
16185         log "$(date +%s): creating first files"
16186         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16187                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16188                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16189         done
16190
16191         # check changelogs have been generated
16192         local start=$SECONDS
16193         local idle_time=$((MDSCOUNT * 5 + 5))
16194         local nbcl=$(changelog_dump | wc -l)
16195         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16196
16197         for param in "changelog_max_idle_time=$idle_time" \
16198                      "changelog_gc=1" \
16199                      "changelog_min_gc_interval=2" \
16200                      "changelog_min_free_cat_entries=3"; do
16201                 local MDT0=$(facet_svc $SINGLEMDS)
16202                 local var="${param%=*}"
16203                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16204
16205                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16206                 do_nodes $mdts $LCTL set_param mdd.*.$param
16207         done
16208
16209         # force cl_user2 to be idle (1st part), but also cancel the
16210         # cl_user1 records so that it is not evicted later in the test.
16211         local sleep1=$((idle_time / 2))
16212         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16213         sleep $sleep1
16214
16215         # simulate changelog catalog almost full
16216         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16217         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16218
16219         for i in $(seq $MDSCOUNT); do
16220                 cl_users=(${CL_USERS[mds$i]})
16221                 cl_user1[mds$i]="${cl_users[0]}"
16222                 cl_user2[mds$i]="${cl_users[1]}"
16223
16224                 [ -n "${cl_user1[mds$i]}" ] ||
16225                         error "mds$i: no user registered"
16226                 [ -n "${cl_user2[mds$i]}" ] ||
16227                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16228
16229                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16230                 [ -n "$user_rec1" ] ||
16231                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16232                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16233                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16234                 [ -n "$user_rec2" ] ||
16235                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16236                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16237                      "$user_rec1 + 2 == $user_rec2"
16238                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16239                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16240                               "$user_rec1 + 2, but is $user_rec2"
16241                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16242                 [ -n "$user_rec2" ] ||
16243                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16244                 [ $user_rec1 == $user_rec2 ] ||
16245                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16246                               "$user_rec1, but is $user_rec2"
16247         done
16248
16249         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16250         local sleep2=$((idle_time - (SECONDS - start) + 1))
16251         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16252         sleep $sleep2
16253
16254         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16255         # cl_user1 should be OK because it recently processed records.
16256         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16257         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16258                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16259                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16260         done
16261
16262         # ensure gc thread is done
16263         for i in $(mdts_nodes); do
16264                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16265                         error "$i: GC-thread not done"
16266         done
16267
16268         local first_rec
16269         for (( i = 1; i <= MDSCOUNT; i++ )); do
16270                 # check cl_user1 still registered
16271                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16272                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16273                 # check cl_user2 unregistered
16274                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16275                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16276
16277                 # check changelogs are present and starting at $user_rec1 + 1
16278                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16279                 [ -n "$user_rec1" ] ||
16280                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16281                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16282                             awk '{ print $1; exit; }')
16283
16284                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16285                 [ $((user_rec1 + 1)) == $first_rec ] ||
16286                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16287         done
16288 }
16289 run_test 160f "changelog garbage collect (timestamped users)"
16290
16291 test_160g() {
16292         remote_mds_nodsh && skip "remote MDS with nodsh"
16293         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16294                 skip "Need MDS version at least 2.14.55"
16295
16296         local mdts=$(comma_list $(mdts_nodes))
16297
16298         # Create a user
16299         changelog_register || error "first changelog_register failed"
16300         changelog_register || error "second changelog_register failed"
16301         local cl_users
16302         declare -A cl_user1
16303         declare -A cl_user2
16304         local user_rec1
16305         local user_rec2
16306         local i
16307
16308         # generate some changelog records to accumulate on each MDT
16309         # use all_char because created files should be evenly distributed
16310         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16311                 error "test_mkdir $tdir failed"
16312         for ((i = 0; i < MDSCOUNT; i++)); do
16313                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16314                         error "create $DIR/$tdir/d$i.1 failed"
16315         done
16316
16317         # check changelogs have been generated
16318         local nbcl=$(changelog_dump | wc -l)
16319         (( $nbcl > 0 )) || error "no changelogs found"
16320
16321         # reduce the max_idle_indexes value to make sure we exceed it
16322         for param in "changelog_max_idle_indexes=2" \
16323                      "changelog_gc=1" \
16324                      "changelog_min_gc_interval=2"; do
16325                 local MDT0=$(facet_svc $SINGLEMDS)
16326                 local var="${param%=*}"
16327                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16328
16329                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16330                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16331                         error "unable to set mdd.*.$param"
16332         done
16333
16334         local start=$SECONDS
16335         for i in $(seq $MDSCOUNT); do
16336                 cl_users=(${CL_USERS[mds$i]})
16337                 cl_user1[mds$i]="${cl_users[0]}"
16338                 cl_user2[mds$i]="${cl_users[1]}"
16339
16340                 [ -n "${cl_user1[mds$i]}" ] ||
16341                         error "mds$i: user1 is not registered"
16342                 [ -n "${cl_user2[mds$i]}" ] ||
16343                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16344
16345                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16346                 [ -n "$user_rec1" ] ||
16347                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16348                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16349                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16350                 [ -n "$user_rec2" ] ||
16351                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16352                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16353                      "$user_rec1 + 2 == $user_rec2"
16354                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16355                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16356                               "expected $user_rec1 + 2, but is $user_rec2"
16357                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16358                 [ -n "$user_rec2" ] ||
16359                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16360                 [ $user_rec1 == $user_rec2 ] ||
16361                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16362                               "expected $user_rec1, but is $user_rec2"
16363         done
16364
16365         # ensure we are past the previous changelog_min_gc_interval set above
16366         local sleep2=$((start + 2 - SECONDS))
16367         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16368         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16369         # cl_user1 should be OK because it recently processed records.
16370         for ((i = 0; i < MDSCOUNT; i++)); do
16371                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16372                         error "create $DIR/$tdir/d$i.3 failed"
16373         done
16374
16375         # ensure gc thread is done
16376         for i in $(mdts_nodes); do
16377                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16378                         error "$i: GC-thread not done"
16379         done
16380
16381         local first_rec
16382         for (( i = 1; i <= MDSCOUNT; i++ )); do
16383                 # check cl_user1 still registered
16384                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16385                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16386                 # check cl_user2 unregistered
16387                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16388                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16389
16390                 # check changelogs are present and starting at $user_rec1 + 1
16391                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16392                 [ -n "$user_rec1" ] ||
16393                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16394                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16395                             awk '{ print $1; exit; }')
16396
16397                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16398                 [ $((user_rec1 + 1)) == $first_rec ] ||
16399                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16400         done
16401 }
16402 run_test 160g "changelog garbage collect on idle records"
16403
16404 test_160h() {
16405         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16406         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16407                 skip "Need MDS version at least 2.10.56"
16408
16409         local mdts=$(comma_list $(mdts_nodes))
16410
16411         # Create a user
16412         changelog_register || error "first changelog_register failed"
16413         changelog_register || error "second changelog_register failed"
16414         local cl_users
16415         declare -A cl_user1
16416         declare -A cl_user2
16417         local user_rec1
16418         local user_rec2
16419         local i
16420
16421         # generate some changelog records to accumulate on each MDT
16422         # use all_char because created files should be evenly distributed
16423         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16424                 error "test_mkdir $tdir failed"
16425         for ((i = 0; i < MDSCOUNT; i++)); do
16426                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16427                         error "create $DIR/$tdir/d$i.1 failed"
16428         done
16429
16430         # check changelogs have been generated
16431         local nbcl=$(changelog_dump | wc -l)
16432         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16433
16434         for param in "changelog_max_idle_time=10" \
16435                      "changelog_gc=1" \
16436                      "changelog_min_gc_interval=2"; do
16437                 local MDT0=$(facet_svc $SINGLEMDS)
16438                 local var="${param%=*}"
16439                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16440
16441                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16442                 do_nodes $mdts $LCTL set_param mdd.*.$param
16443         done
16444
16445         # force cl_user2 to be idle (1st part)
16446         sleep 9
16447
16448         for i in $(seq $MDSCOUNT); do
16449                 cl_users=(${CL_USERS[mds$i]})
16450                 cl_user1[mds$i]="${cl_users[0]}"
16451                 cl_user2[mds$i]="${cl_users[1]}"
16452
16453                 [ -n "${cl_user1[mds$i]}" ] ||
16454                         error "mds$i: no user registered"
16455                 [ -n "${cl_user2[mds$i]}" ] ||
16456                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16457
16458                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16459                 [ -n "$user_rec1" ] ||
16460                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16461                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16462                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16463                 [ -n "$user_rec2" ] ||
16464                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16465                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16466                      "$user_rec1 + 2 == $user_rec2"
16467                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16468                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16469                               "$user_rec1 + 2, but is $user_rec2"
16470                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16471                 [ -n "$user_rec2" ] ||
16472                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16473                 [ $user_rec1 == $user_rec2 ] ||
16474                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16475                               "$user_rec1, but is $user_rec2"
16476         done
16477
16478         # force cl_user2 to be idle (2nd part) and to reach
16479         # changelog_max_idle_time
16480         sleep 2
16481
16482         # force each GC-thread start and block then
16483         # one per MDT/MDD, set fail_val accordingly
16484         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16485         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16486
16487         # generate more changelogs to trigger fail_loc
16488         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16489                 error "create $DIR/$tdir/${tfile}bis failed"
16490
16491         # stop MDT to stop GC-thread, should be done in back-ground as it will
16492         # block waiting for the thread to be released and exit
16493         declare -A stop_pids
16494         for i in $(seq $MDSCOUNT); do
16495                 stop mds$i &
16496                 stop_pids[mds$i]=$!
16497         done
16498
16499         for i in $(mdts_nodes); do
16500                 local facet
16501                 local nb=0
16502                 local facets=$(facets_up_on_host $i)
16503
16504                 for facet in ${facets//,/ }; do
16505                         if [[ $facet == mds* ]]; then
16506                                 nb=$((nb + 1))
16507                         fi
16508                 done
16509                 # ensure each MDS's gc threads are still present and all in "R"
16510                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16511                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16512                         error "$i: expected $nb GC-thread"
16513                 wait_update $i \
16514                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16515                         "R" 20 ||
16516                         error "$i: GC-thread not found in R-state"
16517                 # check umounts of each MDT on MDS have reached kthread_stop()
16518                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16519                         error "$i: expected $nb umount"
16520                 wait_update $i \
16521                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16522                         error "$i: umount not found in D-state"
16523         done
16524
16525         # release all GC-threads
16526         do_nodes $mdts $LCTL set_param fail_loc=0
16527
16528         # wait for MDT stop to complete
16529         for i in $(seq $MDSCOUNT); do
16530                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16531         done
16532
16533         # XXX
16534         # may try to check if any orphan changelog records are present
16535         # via ldiskfs/zfs and llog_reader...
16536
16537         # re-start/mount MDTs
16538         for i in $(seq $MDSCOUNT); do
16539                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16540                         error "Fail to start mds$i"
16541         done
16542
16543         local first_rec
16544         for i in $(seq $MDSCOUNT); do
16545                 # check cl_user1 still registered
16546                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16547                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16548                 # check cl_user2 unregistered
16549                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16550                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16551
16552                 # check changelogs are present and starting at $user_rec1 + 1
16553                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16554                 [ -n "$user_rec1" ] ||
16555                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16556                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16557                             awk '{ print $1; exit; }')
16558
16559                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16560                 [ $((user_rec1 + 1)) == $first_rec ] ||
16561                         error "mds$i: first index should be $user_rec1 + 1, " \
16562                               "but is $first_rec"
16563         done
16564 }
16565 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16566               "during mount"
16567
16568 test_160i() {
16569
16570         local mdts=$(comma_list $(mdts_nodes))
16571
16572         changelog_register || error "first changelog_register failed"
16573
16574         # generate some changelog records to accumulate on each MDT
16575         # use all_char because created files should be evenly distributed
16576         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16577                 error "test_mkdir $tdir failed"
16578         for ((i = 0; i < MDSCOUNT; i++)); do
16579                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16580                         error "create $DIR/$tdir/d$i.1 failed"
16581         done
16582
16583         # check changelogs have been generated
16584         local nbcl=$(changelog_dump | wc -l)
16585         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16586
16587         # simulate race between register and unregister
16588         # XXX as fail_loc is set per-MDS, with DNE configs the race
16589         # simulation will only occur for one MDT per MDS and for the
16590         # others the normal race scenario will take place
16591         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16592         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16593         do_nodes $mdts $LCTL set_param fail_val=1
16594
16595         # unregister 1st user
16596         changelog_deregister &
16597         local pid1=$!
16598         # wait some time for deregister work to reach race rdv
16599         sleep 2
16600         # register 2nd user
16601         changelog_register || error "2nd user register failed"
16602
16603         wait $pid1 || error "1st user deregister failed"
16604
16605         local i
16606         local last_rec
16607         declare -A LAST_REC
16608         for i in $(seq $MDSCOUNT); do
16609                 if changelog_users mds$i | grep "^cl"; then
16610                         # make sure new records are added with one user present
16611                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16612                                           awk '/^current.index:/ { print $NF }')
16613                 else
16614                         error "mds$i has no user registered"
16615                 fi
16616         done
16617
16618         # generate more changelog records to accumulate on each MDT
16619         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16620                 error "create $DIR/$tdir/${tfile}bis failed"
16621
16622         for i in $(seq $MDSCOUNT); do
16623                 last_rec=$(changelog_users $SINGLEMDS |
16624                            awk '/^current.index:/ { print $NF }')
16625                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16626                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16627                         error "changelogs are off on mds$i"
16628         done
16629 }
16630 run_test 160i "changelog user register/unregister race"
16631
16632 test_160j() {
16633         remote_mds_nodsh && skip "remote MDS with nodsh"
16634         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16635                 skip "Need MDS version at least 2.12.56"
16636
16637         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16638         stack_trap "umount $MOUNT2" EXIT
16639
16640         changelog_register || error "first changelog_register failed"
16641         stack_trap "changelog_deregister" EXIT
16642
16643         # generate some changelog
16644         # use all_char because created files should be evenly distributed
16645         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16646                 error "mkdir $tdir failed"
16647         for ((i = 0; i < MDSCOUNT; i++)); do
16648                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16649                         error "create $DIR/$tdir/d$i.1 failed"
16650         done
16651
16652         # open the changelog device
16653         exec 3>/dev/changelog-$FSNAME-MDT0000
16654         stack_trap "exec 3>&-" EXIT
16655         exec 4</dev/changelog-$FSNAME-MDT0000
16656         stack_trap "exec 4<&-" EXIT
16657
16658         # umount the first lustre mount
16659         umount $MOUNT
16660         stack_trap "mount_client $MOUNT" EXIT
16661
16662         # read changelog, which may or may not fail, but should not crash
16663         cat <&4 >/dev/null
16664
16665         # clear changelog
16666         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16667         changelog_users $SINGLEMDS | grep -q $cl_user ||
16668                 error "User $cl_user not found in changelog_users"
16669
16670         printf 'clear:'$cl_user':0' >&3
16671 }
16672 run_test 160j "client can be umounted while its chanangelog is being used"
16673
16674 test_160k() {
16675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16676         remote_mds_nodsh && skip "remote MDS with nodsh"
16677
16678         mkdir -p $DIR/$tdir/1/1
16679
16680         changelog_register || error "changelog_register failed"
16681         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16682
16683         changelog_users $SINGLEMDS | grep -q $cl_user ||
16684                 error "User '$cl_user' not found in changelog_users"
16685 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16686         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16687         rmdir $DIR/$tdir/1/1 & sleep 1
16688         mkdir $DIR/$tdir/2
16689         touch $DIR/$tdir/2/2
16690         rm -rf $DIR/$tdir/2
16691
16692         wait
16693         sleep 4
16694
16695         changelog_dump | grep rmdir || error "rmdir not recorded"
16696 }
16697 run_test 160k "Verify that changelog records are not lost"
16698
16699 # Verifies that a file passed as a parameter has recently had an operation
16700 # performed on it that has generated an MTIME changelog which contains the
16701 # correct parent FID. As files might reside on a different MDT from the
16702 # parent directory in DNE configurations, the FIDs are translated to paths
16703 # before being compared, which should be identical
16704 compare_mtime_changelog() {
16705         local file="${1}"
16706         local mdtidx
16707         local mtime
16708         local cl_fid
16709         local pdir
16710         local dir
16711
16712         mdtidx=$($LFS getstripe --mdt-index $file)
16713         mdtidx=$(printf "%04x" $mdtidx)
16714
16715         # Obtain the parent FID from the MTIME changelog
16716         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16717         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16718
16719         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16720         [ -z "$cl_fid" ] && error "parent FID not present"
16721
16722         # Verify that the path for the parent FID is the same as the path for
16723         # the test directory
16724         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16725
16726         dir=$(dirname $1)
16727
16728         [[ "${pdir%/}" == "$dir" ]] ||
16729                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16730 }
16731
16732 test_160l() {
16733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16734
16735         remote_mds_nodsh && skip "remote MDS with nodsh"
16736         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16737                 skip "Need MDS version at least 2.13.55"
16738
16739         local cl_user
16740
16741         changelog_register || error "changelog_register failed"
16742         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16743
16744         changelog_users $SINGLEMDS | grep -q $cl_user ||
16745                 error "User '$cl_user' not found in changelog_users"
16746
16747         # Clear some types so that MTIME changelogs are generated
16748         changelog_chmask "-CREAT"
16749         changelog_chmask "-CLOSE"
16750
16751         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16752
16753         # Test CL_MTIME during setattr
16754         touch $DIR/$tdir/$tfile
16755         compare_mtime_changelog $DIR/$tdir/$tfile
16756
16757         # Test CL_MTIME during close
16758         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16759         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16760 }
16761 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16762
16763 test_160m() {
16764         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16765         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16766                 skip "Need MDS version at least 2.14.51"
16767         local cl_users
16768         local cl_user1
16769         local cl_user2
16770         local pid1
16771
16772         # Create a user
16773         changelog_register || error "first changelog_register failed"
16774         changelog_register || error "second changelog_register failed"
16775
16776         cl_users=(${CL_USERS[mds1]})
16777         cl_user1="${cl_users[0]}"
16778         cl_user2="${cl_users[1]}"
16779         # generate some changelog records to accumulate on MDT0
16780         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16781         createmany -m $DIR/$tdir/$tfile 50 ||
16782                 error "create $DIR/$tdir/$tfile failed"
16783         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16784         rm -f $DIR/$tdir
16785
16786         # check changelogs have been generated
16787         local nbcl=$(changelog_dump | wc -l)
16788         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16789
16790 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16791         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16792
16793         __changelog_clear mds1 $cl_user1 +10
16794         __changelog_clear mds1 $cl_user2 0 &
16795         pid1=$!
16796         sleep 2
16797         __changelog_clear mds1 $cl_user1 0 ||
16798                 error "fail to cancel record for $cl_user1"
16799         wait $pid1
16800         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16801 }
16802 run_test 160m "Changelog clear race"
16803
16804 test_160n() {
16805         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16806         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16807                 skip "Need MDS version at least 2.14.51"
16808         local cl_users
16809         local cl_user1
16810         local cl_user2
16811         local pid1
16812         local first_rec
16813         local last_rec=0
16814
16815         # Create a user
16816         changelog_register || error "first changelog_register failed"
16817
16818         cl_users=(${CL_USERS[mds1]})
16819         cl_user1="${cl_users[0]}"
16820
16821         # generate some changelog records to accumulate on MDT0
16822         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16823         first_rec=$(changelog_users $SINGLEMDS |
16824                         awk '/^current.index:/ { print $NF }')
16825         while (( last_rec < (( first_rec + 65000)) )); do
16826                 createmany -m $DIR/$tdir/$tfile 10000 ||
16827                         error "create $DIR/$tdir/$tfile failed"
16828
16829                 for i in $(seq 0 10000); do
16830                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16831                                 > /dev/null
16832                 done
16833
16834                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16835                         error "unlinkmany failed unlink"
16836                 last_rec=$(changelog_users $SINGLEMDS |
16837                         awk '/^current.index:/ { print $NF }')
16838                 echo last record $last_rec
16839                 (( last_rec == 0 )) && error "no changelog found"
16840         done
16841
16842 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16843         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16844
16845         __changelog_clear mds1 $cl_user1 0 &
16846         pid1=$!
16847         sleep 2
16848         __changelog_clear mds1 $cl_user1 0 ||
16849                 error "fail to cancel record for $cl_user1"
16850         wait $pid1
16851         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16852 }
16853 run_test 160n "Changelog destroy race"
16854
16855 test_160o() {
16856         local mdt="$(facet_svc $SINGLEMDS)"
16857
16858         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16859         remote_mds_nodsh && skip "remote MDS with nodsh"
16860         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16861                 skip "Need MDS version at least 2.14.52"
16862
16863         changelog_register --user test_160o -m unlnk+close+open ||
16864                 error "changelog_register failed"
16865
16866         do_facet $SINGLEMDS $LCTL --device $mdt \
16867                                 changelog_register -u "Tt3_-#" &&
16868                 error "bad symbols in name should fail"
16869
16870         do_facet $SINGLEMDS $LCTL --device $mdt \
16871                                 changelog_register -u test_160o &&
16872                 error "the same name registration should fail"
16873
16874         do_facet $SINGLEMDS $LCTL --device $mdt \
16875                         changelog_register -u test_160toolongname &&
16876                 error "too long name registration should fail"
16877
16878         changelog_chmask "MARK+HSM"
16879         lctl get_param mdd.*.changelog*mask
16880         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16881         changelog_users $SINGLEMDS | grep -q $cl_user ||
16882                 error "User $cl_user not found in changelog_users"
16883         #verify username
16884         echo $cl_user | grep -q test_160o ||
16885                 error "User $cl_user has no specific name 'test160o'"
16886
16887         # change something
16888         changelog_clear 0 || error "changelog_clear failed"
16889         # generate some changelog records to accumulate on MDT0
16890         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16891         touch $DIR/$tdir/$tfile                 # open 1
16892
16893         OPENS=$(changelog_dump | grep -c "OPEN")
16894         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16895
16896         # must be no MKDIR it wasn't set as user mask
16897         MKDIR=$(changelog_dump | grep -c "MKDIR")
16898         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16899
16900         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16901                                 mdd.$mdt.changelog_current_mask -n)
16902         # register maskless user
16903         changelog_register || error "changelog_register failed"
16904         # effective mask should be not changed because it is not minimal
16905         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16906                                 mdd.$mdt.changelog_current_mask -n)
16907         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16908         # set server mask to minimal value
16909         changelog_chmask "MARK"
16910         # check effective mask again, should be treated as DEFMASK now
16911         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16912                                 mdd.$mdt.changelog_current_mask -n)
16913         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16914
16915         do_facet $SINGLEMDS $LCTL --device $mdt \
16916                                 changelog_deregister -u test_160o ||
16917                 error "cannot deregister by name"
16918 }
16919 run_test 160o "changelog user name and mask"
16920
16921 test_160p() {
16922         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16923         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16924                 skip "Need MDS version at least 2.14.51"
16925         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16926         local cl_users
16927         local cl_user1
16928         local entry_count
16929
16930         # Create a user
16931         changelog_register || error "first changelog_register failed"
16932
16933         cl_users=(${CL_USERS[mds1]})
16934         cl_user1="${cl_users[0]}"
16935
16936         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16937         createmany -m $DIR/$tdir/$tfile 50 ||
16938                 error "create $DIR/$tdir/$tfile failed"
16939         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16940         rm -rf $DIR/$tdir
16941
16942         # check changelogs have been generated
16943         entry_count=$(changelog_dump | wc -l)
16944         ((entry_count != 0)) || error "no changelog entries found"
16945
16946         # remove changelog_users and check that orphan entries are removed
16947         stop mds1
16948         local dev=$(mdsdevname 1)
16949         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16950         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16951         entry_count=$(changelog_dump | wc -l)
16952         ((entry_count == 0)) ||
16953                 error "found $entry_count changelog entries, expected none"
16954 }
16955 run_test 160p "Changelog orphan cleanup with no users"
16956
16957 test_160q() {
16958         local mdt="$(facet_svc $SINGLEMDS)"
16959         local clu
16960
16961         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16962         remote_mds_nodsh && skip "remote MDS with nodsh"
16963         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16964                 skip "Need MDS version at least 2.14.54"
16965
16966         # set server mask to minimal value like server init does
16967         changelog_chmask "MARK"
16968         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16969                 error "changelog_register failed"
16970         # check effective mask again, should be treated as DEFMASK now
16971         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16972                                 mdd.$mdt.changelog_current_mask -n)
16973         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16974                 error "changelog_deregister failed"
16975         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16976 }
16977 run_test 160q "changelog effective mask is DEFMASK if not set"
16978
16979 test_160s() {
16980         remote_mds_nodsh && skip "remote MDS with nodsh"
16981         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16982                 skip "Need MDS version at least 2.14.55"
16983
16984         local mdts=$(comma_list $(mdts_nodes))
16985
16986         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16987         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16988                                        fail_val=$((24 * 3600 * 10))
16989
16990         # Create a user which is 10 days old
16991         changelog_register || error "first changelog_register failed"
16992         local cl_users
16993         declare -A cl_user1
16994         local i
16995
16996         # generate some changelog records to accumulate on each MDT
16997         # use all_char because created files should be evenly distributed
16998         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16999                 error "test_mkdir $tdir failed"
17000         for ((i = 0; i < MDSCOUNT; i++)); do
17001                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17002                         error "create $DIR/$tdir/d$i.1 failed"
17003         done
17004
17005         # check changelogs have been generated
17006         local nbcl=$(changelog_dump | wc -l)
17007         (( nbcl > 0 )) || error "no changelogs found"
17008
17009         # reduce the max_idle_indexes value to make sure we exceed it
17010         for param in "changelog_max_idle_indexes=2097446912" \
17011                      "changelog_max_idle_time=2592000" \
17012                      "changelog_gc=1" \
17013                      "changelog_min_gc_interval=2"; do
17014                 local MDT0=$(facet_svc $SINGLEMDS)
17015                 local var="${param%=*}"
17016                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17017
17018                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17019                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17020                         error "unable to set mdd.*.$param"
17021         done
17022
17023         local start=$SECONDS
17024         for i in $(seq $MDSCOUNT); do
17025                 cl_users=(${CL_USERS[mds$i]})
17026                 cl_user1[mds$i]="${cl_users[0]}"
17027
17028                 [[ -n "${cl_user1[mds$i]}" ]] ||
17029                         error "mds$i: no user registered"
17030         done
17031
17032         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17033         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17034
17035         # ensure we are past the previous changelog_min_gc_interval set above
17036         local sleep2=$((start + 2 - SECONDS))
17037         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17038
17039         # Generate one more changelog to trigger GC
17040         for ((i = 0; i < MDSCOUNT; i++)); do
17041                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17042                         error "create $DIR/$tdir/d$i.3 failed"
17043         done
17044
17045         # ensure gc thread is done
17046         for node in $(mdts_nodes); do
17047                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17048                         error "$node: GC-thread not done"
17049         done
17050
17051         do_nodes $mdts $LCTL set_param fail_loc=0
17052
17053         for (( i = 1; i <= MDSCOUNT; i++ )); do
17054                 # check cl_user1 is purged
17055                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17056                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17057         done
17058         return 0
17059 }
17060 run_test 160s "changelog garbage collect on idle records * time"
17061
17062 test_161a() {
17063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17064
17065         test_mkdir -c1 $DIR/$tdir
17066         cp /etc/hosts $DIR/$tdir/$tfile
17067         test_mkdir -c1 $DIR/$tdir/foo1
17068         test_mkdir -c1 $DIR/$tdir/foo2
17069         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17070         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17071         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17072         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17073         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17074         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17075                 $LFS fid2path $DIR $FID
17076                 error "bad link ea"
17077         fi
17078         # middle
17079         rm $DIR/$tdir/foo2/zachary
17080         # last
17081         rm $DIR/$tdir/foo2/thor
17082         # first
17083         rm $DIR/$tdir/$tfile
17084         # rename
17085         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17086         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17087                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17088         rm $DIR/$tdir/foo2/maggie
17089
17090         # overflow the EA
17091         local longname=$tfile.avg_len_is_thirty_two_
17092         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17093                 error_noexit 'failed to unlink many hardlinks'" EXIT
17094         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17095                 error "failed to hardlink many files"
17096         links=$($LFS fid2path $DIR $FID | wc -l)
17097         echo -n "${links}/1000 links in link EA"
17098         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17099 }
17100 run_test 161a "link ea sanity"
17101
17102 test_161b() {
17103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17104         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17105
17106         local MDTIDX=1
17107         local remote_dir=$DIR/$tdir/remote_dir
17108
17109         mkdir -p $DIR/$tdir
17110         $LFS mkdir -i $MDTIDX $remote_dir ||
17111                 error "create remote directory failed"
17112
17113         cp /etc/hosts $remote_dir/$tfile
17114         mkdir -p $remote_dir/foo1
17115         mkdir -p $remote_dir/foo2
17116         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17117         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17118         ln $remote_dir/$tfile $remote_dir/foo1/luna
17119         ln $remote_dir/$tfile $remote_dir/foo2/thor
17120
17121         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17122                      tr -d ']')
17123         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17124                 $LFS fid2path $DIR $FID
17125                 error "bad link ea"
17126         fi
17127         # middle
17128         rm $remote_dir/foo2/zachary
17129         # last
17130         rm $remote_dir/foo2/thor
17131         # first
17132         rm $remote_dir/$tfile
17133         # rename
17134         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17135         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17136         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17137                 $LFS fid2path $DIR $FID
17138                 error "bad link rename"
17139         fi
17140         rm $remote_dir/foo2/maggie
17141
17142         # overflow the EA
17143         local longname=filename_avg_len_is_thirty_two_
17144         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17145                 error "failed to hardlink many files"
17146         links=$($LFS fid2path $DIR $FID | wc -l)
17147         echo -n "${links}/1000 links in link EA"
17148         [[ ${links} -gt 60 ]] ||
17149                 error "expected at least 60 links in link EA"
17150         unlinkmany $remote_dir/foo2/$longname 1000 ||
17151         error "failed to unlink many hardlinks"
17152 }
17153 run_test 161b "link ea sanity under remote directory"
17154
17155 test_161c() {
17156         remote_mds_nodsh && skip "remote MDS with nodsh"
17157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17158         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17159                 skip "Need MDS version at least 2.1.5"
17160
17161         # define CLF_RENAME_LAST 0x0001
17162         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17163         changelog_register || error "changelog_register failed"
17164
17165         rm -rf $DIR/$tdir
17166         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17167         touch $DIR/$tdir/foo_161c
17168         touch $DIR/$tdir/bar_161c
17169         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17170         changelog_dump | grep RENME | tail -n 5
17171         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17172         changelog_clear 0 || error "changelog_clear failed"
17173         if [ x$flags != "x0x1" ]; then
17174                 error "flag $flags is not 0x1"
17175         fi
17176
17177         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17178         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17179         touch $DIR/$tdir/foo_161c
17180         touch $DIR/$tdir/bar_161c
17181         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17182         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17183         changelog_dump | grep RENME | tail -n 5
17184         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17185         changelog_clear 0 || error "changelog_clear failed"
17186         if [ x$flags != "x0x0" ]; then
17187                 error "flag $flags is not 0x0"
17188         fi
17189         echo "rename overwrite a target having nlink > 1," \
17190                 "changelog record has flags of $flags"
17191
17192         # rename doesn't overwrite a target (changelog flag 0x0)
17193         touch $DIR/$tdir/foo_161c
17194         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17195         changelog_dump | grep RENME | tail -n 5
17196         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17197         changelog_clear 0 || error "changelog_clear failed"
17198         if [ x$flags != "x0x0" ]; then
17199                 error "flag $flags is not 0x0"
17200         fi
17201         echo "rename doesn't overwrite a target," \
17202                 "changelog record has flags of $flags"
17203
17204         # define CLF_UNLINK_LAST 0x0001
17205         # unlink a file having nlink = 1 (changelog flag 0x1)
17206         rm -f $DIR/$tdir/foo2_161c
17207         changelog_dump | grep UNLNK | tail -n 5
17208         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17209         changelog_clear 0 || error "changelog_clear failed"
17210         if [ x$flags != "x0x1" ]; then
17211                 error "flag $flags is not 0x1"
17212         fi
17213         echo "unlink a file having nlink = 1," \
17214                 "changelog record has flags of $flags"
17215
17216         # unlink a file having nlink > 1 (changelog flag 0x0)
17217         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17218         rm -f $DIR/$tdir/foobar_161c
17219         changelog_dump | grep UNLNK | tail -n 5
17220         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17221         changelog_clear 0 || error "changelog_clear failed"
17222         if [ x$flags != "x0x0" ]; then
17223                 error "flag $flags is not 0x0"
17224         fi
17225         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17226 }
17227 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17228
17229 test_161d() {
17230         remote_mds_nodsh && skip "remote MDS with nodsh"
17231         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17232
17233         local pid
17234         local fid
17235
17236         changelog_register || error "changelog_register failed"
17237
17238         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17239         # interfer with $MOUNT/.lustre/fid/ access
17240         mkdir $DIR/$tdir
17241         [[ $? -eq 0 ]] || error "mkdir failed"
17242
17243         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17244         $LCTL set_param fail_loc=0x8000140c
17245         # 5s pause
17246         $LCTL set_param fail_val=5
17247
17248         # create file
17249         echo foofoo > $DIR/$tdir/$tfile &
17250         pid=$!
17251
17252         # wait for create to be delayed
17253         sleep 2
17254
17255         ps -p $pid
17256         [[ $? -eq 0 ]] || error "create should be blocked"
17257
17258         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17259         stack_trap "rm -f $tempfile"
17260         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17261         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17262         # some delay may occur during ChangeLog publishing and file read just
17263         # above, that could allow file write to happen finally
17264         [[ -s $tempfile ]] && echo "file should be empty"
17265
17266         $LCTL set_param fail_loc=0
17267
17268         wait $pid
17269         [[ $? -eq 0 ]] || error "create failed"
17270 }
17271 run_test 161d "create with concurrent .lustre/fid access"
17272
17273 check_path() {
17274         local expected="$1"
17275         shift
17276         local fid="$2"
17277
17278         local path
17279         path=$($LFS fid2path "$@")
17280         local rc=$?
17281
17282         if [ $rc -ne 0 ]; then
17283                 error "path looked up of '$expected' failed: rc=$rc"
17284         elif [ "$path" != "$expected" ]; then
17285                 error "path looked up '$path' instead of '$expected'"
17286         else
17287                 echo "FID '$fid' resolves to path '$path' as expected"
17288         fi
17289 }
17290
17291 test_162a() { # was test_162
17292         test_mkdir -p -c1 $DIR/$tdir/d2
17293         touch $DIR/$tdir/d2/$tfile
17294         touch $DIR/$tdir/d2/x1
17295         touch $DIR/$tdir/d2/x2
17296         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17297         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17298         # regular file
17299         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17300         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17301
17302         # softlink
17303         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17304         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17305         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17306
17307         # softlink to wrong file
17308         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17309         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17310         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17311
17312         # hardlink
17313         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17314         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17315         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17316         # fid2path dir/fsname should both work
17317         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17318         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17319
17320         # hardlink count: check that there are 2 links
17321         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17322         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17323
17324         # hardlink indexing: remove the first link
17325         rm $DIR/$tdir/d2/p/q/r/hlink
17326         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17327 }
17328 run_test 162a "path lookup sanity"
17329
17330 test_162b() {
17331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17333
17334         mkdir $DIR/$tdir
17335         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17336                                 error "create striped dir failed"
17337
17338         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17339                                         tail -n 1 | awk '{print $2}')
17340         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17341
17342         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17343         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17344
17345         # regular file
17346         for ((i=0;i<5;i++)); do
17347                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17348                         error "get fid for f$i failed"
17349                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17350
17351                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17352                         error "get fid for d$i failed"
17353                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17354         done
17355
17356         return 0
17357 }
17358 run_test 162b "striped directory path lookup sanity"
17359
17360 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17361 test_162c() {
17362         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17363                 skip "Need MDS version at least 2.7.51"
17364
17365         local lpath=$tdir.local
17366         local rpath=$tdir.remote
17367
17368         test_mkdir $DIR/$lpath
17369         test_mkdir $DIR/$rpath
17370
17371         for ((i = 0; i <= 101; i++)); do
17372                 lpath="$lpath/$i"
17373                 mkdir $DIR/$lpath
17374                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17375                         error "get fid for local directory $DIR/$lpath failed"
17376                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17377
17378                 rpath="$rpath/$i"
17379                 test_mkdir $DIR/$rpath
17380                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17381                         error "get fid for remote directory $DIR/$rpath failed"
17382                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17383         done
17384
17385         return 0
17386 }
17387 run_test 162c "fid2path works with paths 100 or more directories deep"
17388
17389 oalr_event_count() {
17390         local event="${1}"
17391         local trace="${2}"
17392
17393         awk -v name="${FSNAME}-OST0000" \
17394             -v event="${event}" \
17395             '$1 == "TRACE" && $2 == event && $3 == name' \
17396             "${trace}" |
17397         wc -l
17398 }
17399
17400 oalr_expect_event_count() {
17401         local event="${1}"
17402         local trace="${2}"
17403         local expect="${3}"
17404         local count
17405
17406         count=$(oalr_event_count "${event}" "${trace}")
17407         if ((count == expect)); then
17408                 return 0
17409         fi
17410
17411         error_noexit "${event} event count was '${count}', expected ${expect}"
17412         cat "${trace}" >&2
17413         exit 1
17414 }
17415
17416 cleanup_165() {
17417         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17418         stop ost1
17419         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17420 }
17421
17422 setup_165() {
17423         sync # Flush previous IOs so we can count log entries.
17424         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17425         stack_trap cleanup_165 EXIT
17426 }
17427
17428 test_165a() {
17429         local trace="/tmp/${tfile}.trace"
17430         local rc
17431         local count
17432
17433         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17434                 skip "OFD access log unsupported"
17435
17436         setup_165
17437         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17438         sleep 5
17439
17440         do_facet ost1 ofd_access_log_reader --list
17441         stop ost1
17442
17443         do_facet ost1 killall -TERM ofd_access_log_reader
17444         wait
17445         rc=$?
17446
17447         if ((rc != 0)); then
17448                 error "ofd_access_log_reader exited with rc = '${rc}'"
17449         fi
17450
17451         # Parse trace file for discovery events:
17452         oalr_expect_event_count alr_log_add "${trace}" 1
17453         oalr_expect_event_count alr_log_eof "${trace}" 1
17454         oalr_expect_event_count alr_log_free "${trace}" 1
17455 }
17456 run_test 165a "ofd access log discovery"
17457
17458 test_165b() {
17459         local trace="/tmp/${tfile}.trace"
17460         local file="${DIR}/${tfile}"
17461         local pfid1
17462         local pfid2
17463         local -a entry
17464         local rc
17465         local count
17466         local size
17467         local flags
17468
17469         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17470                 skip "OFD access log unsupported"
17471
17472         setup_165
17473         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17474         sleep 5
17475
17476         do_facet ost1 ofd_access_log_reader --list
17477
17478         lfs setstripe -c 1 -i 0 "${file}"
17479         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17480                 error "cannot create '${file}'"
17481
17482         sleep 5
17483         do_facet ost1 killall -TERM ofd_access_log_reader
17484         wait
17485         rc=$?
17486
17487         if ((rc != 0)); then
17488                 error "ofd_access_log_reader exited with rc = '${rc}'"
17489         fi
17490
17491         oalr_expect_event_count alr_log_entry "${trace}" 1
17492
17493         pfid1=$($LFS path2fid "${file}")
17494
17495         # 1     2             3   4    5     6   7    8    9     10
17496         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17497         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17498
17499         echo "entry = '${entry[*]}'" >&2
17500
17501         pfid2=${entry[4]}
17502         if [[ "${pfid1}" != "${pfid2}" ]]; then
17503                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17504         fi
17505
17506         size=${entry[8]}
17507         if ((size != 1048576)); then
17508                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17509         fi
17510
17511         flags=${entry[10]}
17512         if [[ "${flags}" != "w" ]]; then
17513                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17514         fi
17515
17516         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17517         sleep 5
17518
17519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17520                 error "cannot read '${file}'"
17521         sleep 5
17522
17523         do_facet ost1 killall -TERM ofd_access_log_reader
17524         wait
17525         rc=$?
17526
17527         if ((rc != 0)); then
17528                 error "ofd_access_log_reader exited with rc = '${rc}'"
17529         fi
17530
17531         oalr_expect_event_count alr_log_entry "${trace}" 1
17532
17533         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17534         echo "entry = '${entry[*]}'" >&2
17535
17536         pfid2=${entry[4]}
17537         if [[ "${pfid1}" != "${pfid2}" ]]; then
17538                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17539         fi
17540
17541         size=${entry[8]}
17542         if ((size != 524288)); then
17543                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17544         fi
17545
17546         flags=${entry[10]}
17547         if [[ "${flags}" != "r" ]]; then
17548                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17549         fi
17550 }
17551 run_test 165b "ofd access log entries are produced and consumed"
17552
17553 test_165c() {
17554         local trace="/tmp/${tfile}.trace"
17555         local file="${DIR}/${tdir}/${tfile}"
17556
17557         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17558                 skip "OFD access log unsupported"
17559
17560         test_mkdir "${DIR}/${tdir}"
17561
17562         setup_165
17563         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17564         sleep 5
17565
17566         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17567
17568         # 4096 / 64 = 64. Create twice as many entries.
17569         for ((i = 0; i < 128; i++)); do
17570                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17571                         error "cannot create file"
17572         done
17573
17574         sync
17575
17576         do_facet ost1 killall -TERM ofd_access_log_reader
17577         wait
17578         rc=$?
17579         if ((rc != 0)); then
17580                 error "ofd_access_log_reader exited with rc = '${rc}'"
17581         fi
17582
17583         unlinkmany  "${file}-%d" 128
17584 }
17585 run_test 165c "full ofd access logs do not block IOs"
17586
17587 oal_get_read_count() {
17588         local stats="$1"
17589
17590         # STATS lustre-OST0001 alr_read_count 1
17591
17592         do_facet ost1 cat "${stats}" |
17593         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17594              END { print count; }'
17595 }
17596
17597 oal_expect_read_count() {
17598         local stats="$1"
17599         local count
17600         local expect="$2"
17601
17602         # Ask ofd_access_log_reader to write stats.
17603         do_facet ost1 killall -USR1 ofd_access_log_reader
17604
17605         # Allow some time for things to happen.
17606         sleep 1
17607
17608         count=$(oal_get_read_count "${stats}")
17609         if ((count == expect)); then
17610                 return 0
17611         fi
17612
17613         error_noexit "bad read count, got ${count}, expected ${expect}"
17614         do_facet ost1 cat "${stats}" >&2
17615         exit 1
17616 }
17617
17618 test_165d() {
17619         local stats="/tmp/${tfile}.stats"
17620         local file="${DIR}/${tdir}/${tfile}"
17621         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17622
17623         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17624                 skip "OFD access log unsupported"
17625
17626         test_mkdir "${DIR}/${tdir}"
17627
17628         setup_165
17629         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17630         sleep 5
17631
17632         lfs setstripe -c 1 -i 0 "${file}"
17633
17634         do_facet ost1 lctl set_param "${param}=rw"
17635         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17636                 error "cannot create '${file}'"
17637         oal_expect_read_count "${stats}" 1
17638
17639         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17640                 error "cannot read '${file}'"
17641         oal_expect_read_count "${stats}" 2
17642
17643         do_facet ost1 lctl set_param "${param}=r"
17644         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17645                 error "cannot create '${file}'"
17646         oal_expect_read_count "${stats}" 2
17647
17648         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17649                 error "cannot read '${file}'"
17650         oal_expect_read_count "${stats}" 3
17651
17652         do_facet ost1 lctl set_param "${param}=w"
17653         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17654                 error "cannot create '${file}'"
17655         oal_expect_read_count "${stats}" 4
17656
17657         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17658                 error "cannot read '${file}'"
17659         oal_expect_read_count "${stats}" 4
17660
17661         do_facet ost1 lctl set_param "${param}=0"
17662         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17663                 error "cannot create '${file}'"
17664         oal_expect_read_count "${stats}" 4
17665
17666         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17667                 error "cannot read '${file}'"
17668         oal_expect_read_count "${stats}" 4
17669
17670         do_facet ost1 killall -TERM ofd_access_log_reader
17671         wait
17672         rc=$?
17673         if ((rc != 0)); then
17674                 error "ofd_access_log_reader exited with rc = '${rc}'"
17675         fi
17676 }
17677 run_test 165d "ofd_access_log mask works"
17678
17679 test_165e() {
17680         local stats="/tmp/${tfile}.stats"
17681         local file0="${DIR}/${tdir}-0/${tfile}"
17682         local file1="${DIR}/${tdir}-1/${tfile}"
17683
17684         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17685                 skip "OFD access log unsupported"
17686
17687         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17688
17689         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17690         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17691
17692         lfs setstripe -c 1 -i 0 "${file0}"
17693         lfs setstripe -c 1 -i 0 "${file1}"
17694
17695         setup_165
17696         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17697         sleep 5
17698
17699         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17700                 error "cannot create '${file0}'"
17701         sync
17702         oal_expect_read_count "${stats}" 0
17703
17704         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17705                 error "cannot create '${file1}'"
17706         sync
17707         oal_expect_read_count "${stats}" 1
17708
17709         do_facet ost1 killall -TERM ofd_access_log_reader
17710         wait
17711         rc=$?
17712         if ((rc != 0)); then
17713                 error "ofd_access_log_reader exited with rc = '${rc}'"
17714         fi
17715 }
17716 run_test 165e "ofd_access_log MDT index filter works"
17717
17718 test_165f() {
17719         local trace="/tmp/${tfile}.trace"
17720         local rc
17721         local count
17722
17723         setup_165
17724         do_facet ost1 timeout 60 ofd_access_log_reader \
17725                 --exit-on-close --debug=- --trace=- > "${trace}" &
17726         sleep 5
17727         stop ost1
17728
17729         wait
17730         rc=$?
17731
17732         if ((rc != 0)); then
17733                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17734                 cat "${trace}"
17735                 exit 1
17736         fi
17737 }
17738 run_test 165f "ofd_access_log_reader --exit-on-close works"
17739
17740 test_169() {
17741         # do directio so as not to populate the page cache
17742         log "creating a 10 Mb file"
17743         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17744                 error "multiop failed while creating a file"
17745         log "starting reads"
17746         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17747         log "truncating the file"
17748         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17749                 error "multiop failed while truncating the file"
17750         log "killing dd"
17751         kill %+ || true # reads might have finished
17752         echo "wait until dd is finished"
17753         wait
17754         log "removing the temporary file"
17755         rm -rf $DIR/$tfile || error "tmp file removal failed"
17756 }
17757 run_test 169 "parallel read and truncate should not deadlock"
17758
17759 test_170() {
17760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17761
17762         $LCTL clear     # bug 18514
17763         $LCTL debug_daemon start $TMP/${tfile}_log_good
17764         touch $DIR/$tfile
17765         $LCTL debug_daemon stop
17766         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17767                 error "sed failed to read log_good"
17768
17769         $LCTL debug_daemon start $TMP/${tfile}_log_good
17770         rm -rf $DIR/$tfile
17771         $LCTL debug_daemon stop
17772
17773         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17774                error "lctl df log_bad failed"
17775
17776         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17777         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17778
17779         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17780         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17781
17782         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17783                 error "bad_line good_line1 good_line2 are empty"
17784
17785         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17786         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17787         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17788
17789         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17790         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17791         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17792
17793         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17794                 error "bad_line_new good_line_new are empty"
17795
17796         local expected_good=$((good_line1 + good_line2*2))
17797
17798         rm -f $TMP/${tfile}*
17799         # LU-231, short malformed line may not be counted into bad lines
17800         if [ $bad_line -ne $bad_line_new ] &&
17801                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17802                 error "expected $bad_line bad lines, but got $bad_line_new"
17803                 return 1
17804         fi
17805
17806         if [ $expected_good -ne $good_line_new ]; then
17807                 error "expected $expected_good good lines, but got $good_line_new"
17808                 return 2
17809         fi
17810         true
17811 }
17812 run_test 170 "test lctl df to handle corrupted log ====================="
17813
17814 test_171() { # bug20592
17815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17816
17817         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17818         $LCTL set_param fail_loc=0x50e
17819         $LCTL set_param fail_val=3000
17820         multiop_bg_pause $DIR/$tfile O_s || true
17821         local MULTIPID=$!
17822         kill -USR1 $MULTIPID
17823         # cause log dump
17824         sleep 3
17825         wait $MULTIPID
17826         if dmesg | grep "recursive fault"; then
17827                 error "caught a recursive fault"
17828         fi
17829         $LCTL set_param fail_loc=0
17830         true
17831 }
17832 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17833
17834 test_172() {
17835
17836         #define OBD_FAIL_OBD_CLEANUP  0x60e
17837         $LCTL set_param fail_loc=0x60e
17838         umount $MOUNT || error "umount $MOUNT failed"
17839         stack_trap "mount_client $MOUNT"
17840
17841         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17842                 error "no client OBDs are remained"
17843
17844         $LCTL dl | while read devno state type name foo; do
17845                 case $type in
17846                 lov|osc|lmv|mdc)
17847                         $LCTL --device $name cleanup
17848                         $LCTL --device $name detach
17849                         ;;
17850                 *)
17851                         # skip server devices
17852                         ;;
17853                 esac
17854         done
17855
17856         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17857                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17858                 error "some client OBDs are still remained"
17859         fi
17860
17861 }
17862 run_test 172 "manual device removal with lctl cleanup/detach ======"
17863
17864 # it would be good to share it with obdfilter-survey/iokit-libecho code
17865 setup_obdecho_osc () {
17866         local rc=0
17867         local ost_nid=$1
17868         local obdfilter_name=$2
17869         echo "Creating new osc for $obdfilter_name on $ost_nid"
17870         # make sure we can find loopback nid
17871         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17872
17873         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17874                            ${obdfilter_name}_osc_UUID || rc=2; }
17875         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17876                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17877         return $rc
17878 }
17879
17880 cleanup_obdecho_osc () {
17881         local obdfilter_name=$1
17882         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17883         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17884         return 0
17885 }
17886
17887 obdecho_test() {
17888         local OBD=$1
17889         local node=$2
17890         local pages=${3:-64}
17891         local rc=0
17892         local id
17893
17894         local count=10
17895         local obd_size=$(get_obd_size $node $OBD)
17896         local page_size=$(get_page_size $node)
17897         if [[ -n "$obd_size" ]]; then
17898                 local new_count=$((obd_size / (pages * page_size / 1024)))
17899                 [[ $new_count -ge $count ]] || count=$new_count
17900         fi
17901
17902         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17903         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17904                            rc=2; }
17905         if [ $rc -eq 0 ]; then
17906             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17907             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17908         fi
17909         echo "New object id is $id"
17910         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17911                            rc=4; }
17912         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17913                            "test_brw $count w v $pages $id" || rc=4; }
17914         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17915                            rc=4; }
17916         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17917                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17918         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17919                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17920         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17921         return $rc
17922 }
17923
17924 test_180a() {
17925         skip "obdecho on osc is no longer supported"
17926 }
17927 run_test 180a "test obdecho on osc"
17928
17929 test_180b() {
17930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17931         remote_ost_nodsh && skip "remote OST with nodsh"
17932
17933         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17934                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17935                 error "failed to load module obdecho"
17936
17937         local target=$(do_facet ost1 $LCTL dl |
17938                        awk '/obdfilter/ { print $4; exit; }')
17939
17940         if [ -n "$target" ]; then
17941                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17942         else
17943                 do_facet ost1 $LCTL dl
17944                 error "there is no obdfilter target on ost1"
17945         fi
17946 }
17947 run_test 180b "test obdecho directly on obdfilter"
17948
17949 test_180c() { # LU-2598
17950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17951         remote_ost_nodsh && skip "remote OST with nodsh"
17952         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17953                 skip "Need MDS version at least 2.4.0"
17954
17955         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17956                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17957                 error "failed to load module obdecho"
17958
17959         local target=$(do_facet ost1 $LCTL dl |
17960                        awk '/obdfilter/ { print $4; exit; }')
17961
17962         if [ -n "$target" ]; then
17963                 local pages=16384 # 64MB bulk I/O RPC size
17964
17965                 obdecho_test "$target" ost1 "$pages" ||
17966                         error "obdecho_test with pages=$pages failed with $?"
17967         else
17968                 do_facet ost1 $LCTL dl
17969                 error "there is no obdfilter target on ost1"
17970         fi
17971 }
17972 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17973
17974 test_181() { # bug 22177
17975         test_mkdir $DIR/$tdir
17976         # create enough files to index the directory
17977         createmany -o $DIR/$tdir/foobar 4000
17978         # print attributes for debug purpose
17979         lsattr -d .
17980         # open dir
17981         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17982         MULTIPID=$!
17983         # remove the files & current working dir
17984         unlinkmany $DIR/$tdir/foobar 4000
17985         rmdir $DIR/$tdir
17986         kill -USR1 $MULTIPID
17987         wait $MULTIPID
17988         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17989         return 0
17990 }
17991 run_test 181 "Test open-unlinked dir ========================"
17992
17993 test_182a() {
17994         local fcount=1000
17995         local tcount=10
17996
17997         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17998
17999         $LCTL set_param mdc.*.rpc_stats=clear
18000
18001         for (( i = 0; i < $tcount; i++ )) ; do
18002                 mkdir $DIR/$tdir/$i
18003         done
18004
18005         for (( i = 0; i < $tcount; i++ )) ; do
18006                 createmany -o $DIR/$tdir/$i/f- $fcount &
18007         done
18008         wait
18009
18010         for (( i = 0; i < $tcount; i++ )) ; do
18011                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18012         done
18013         wait
18014
18015         $LCTL get_param mdc.*.rpc_stats
18016
18017         rm -rf $DIR/$tdir
18018 }
18019 run_test 182a "Test parallel modify metadata operations from mdc"
18020
18021 test_182b() {
18022         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18023         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18024         local dcount=1000
18025         local tcount=10
18026         local stime
18027         local etime
18028         local delta
18029
18030         do_facet mds1 $LCTL list_param \
18031                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18032                 skip "MDS lacks parallel RPC handling"
18033
18034         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18035
18036         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18037                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18038
18039         stime=$(date +%s)
18040         createmany -i 0 -d $DIR/$tdir/t- $tcount
18041
18042         for (( i = 0; i < $tcount; i++ )) ; do
18043                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18044         done
18045         wait
18046         etime=$(date +%s)
18047         delta=$((etime - stime))
18048         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18049
18050         stime=$(date +%s)
18051         for (( i = 0; i < $tcount; i++ )) ; do
18052                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18053         done
18054         wait
18055         etime=$(date +%s)
18056         delta=$((etime - stime))
18057         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18058
18059         rm -rf $DIR/$tdir
18060
18061         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18062
18063         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18064
18065         stime=$(date +%s)
18066         createmany -i 0 -d $DIR/$tdir/t- $tcount
18067
18068         for (( i = 0; i < $tcount; i++ )) ; do
18069                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18070         done
18071         wait
18072         etime=$(date +%s)
18073         delta=$((etime - stime))
18074         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18075
18076         stime=$(date +%s)
18077         for (( i = 0; i < $tcount; i++ )) ; do
18078                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18079         done
18080         wait
18081         etime=$(date +%s)
18082         delta=$((etime - stime))
18083         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18084
18085         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18086 }
18087 run_test 182b "Test parallel modify metadata operations from osp"
18088
18089 test_183() { # LU-2275
18090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18093                 skip "Need MDS version at least 2.3.56"
18094
18095         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18096         echo aaa > $DIR/$tdir/$tfile
18097
18098 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18099         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18100
18101         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18102         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18103
18104         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18105
18106         # Flush negative dentry cache
18107         touch $DIR/$tdir/$tfile
18108
18109         # We are not checking for any leaked references here, they'll
18110         # become evident next time we do cleanup with module unload.
18111         rm -rf $DIR/$tdir
18112 }
18113 run_test 183 "No crash or request leak in case of strange dispositions ========"
18114
18115 # test suite 184 is for LU-2016, LU-2017
18116 test_184a() {
18117         check_swap_layouts_support
18118
18119         dir0=$DIR/$tdir/$testnum
18120         test_mkdir -p -c1 $dir0
18121         ref1=/etc/passwd
18122         ref2=/etc/group
18123         file1=$dir0/f1
18124         file2=$dir0/f2
18125         $LFS setstripe -c1 $file1
18126         cp $ref1 $file1
18127         $LFS setstripe -c2 $file2
18128         cp $ref2 $file2
18129         gen1=$($LFS getstripe -g $file1)
18130         gen2=$($LFS getstripe -g $file2)
18131
18132         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18133         gen=$($LFS getstripe -g $file1)
18134         [[ $gen1 != $gen ]] ||
18135                 error "Layout generation on $file1 does not change"
18136         gen=$($LFS getstripe -g $file2)
18137         [[ $gen2 != $gen ]] ||
18138                 error "Layout generation on $file2 does not change"
18139
18140         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18141         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18142
18143         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18144 }
18145 run_test 184a "Basic layout swap"
18146
18147 test_184b() {
18148         check_swap_layouts_support
18149
18150         dir0=$DIR/$tdir/$testnum
18151         mkdir -p $dir0 || error "creating dir $dir0"
18152         file1=$dir0/f1
18153         file2=$dir0/f2
18154         file3=$dir0/f3
18155         dir1=$dir0/d1
18156         dir2=$dir0/d2
18157         mkdir $dir1 $dir2
18158         $LFS setstripe -c1 $file1
18159         $LFS setstripe -c2 $file2
18160         $LFS setstripe -c1 $file3
18161         chown $RUNAS_ID $file3
18162         gen1=$($LFS getstripe -g $file1)
18163         gen2=$($LFS getstripe -g $file2)
18164
18165         $LFS swap_layouts $dir1 $dir2 &&
18166                 error "swap of directories layouts should fail"
18167         $LFS swap_layouts $dir1 $file1 &&
18168                 error "swap of directory and file layouts should fail"
18169         $RUNAS $LFS swap_layouts $file1 $file2 &&
18170                 error "swap of file we cannot write should fail"
18171         $LFS swap_layouts $file1 $file3 &&
18172                 error "swap of file with different owner should fail"
18173         /bin/true # to clear error code
18174 }
18175 run_test 184b "Forbidden layout swap (will generate errors)"
18176
18177 test_184c() {
18178         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18179         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18180         check_swap_layouts_support
18181         check_swap_layout_no_dom $DIR
18182
18183         local dir0=$DIR/$tdir/$testnum
18184         mkdir -p $dir0 || error "creating dir $dir0"
18185
18186         local ref1=$dir0/ref1
18187         local ref2=$dir0/ref2
18188         local file1=$dir0/file1
18189         local file2=$dir0/file2
18190         # create a file large enough for the concurrent test
18191         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18192         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18193         echo "ref file size: ref1($(stat -c %s $ref1))," \
18194              "ref2($(stat -c %s $ref2))"
18195
18196         cp $ref2 $file2
18197         dd if=$ref1 of=$file1 bs=16k &
18198         local DD_PID=$!
18199
18200         # Make sure dd starts to copy file, but wait at most 5 seconds
18201         local loops=0
18202         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18203
18204         $LFS swap_layouts $file1 $file2
18205         local rc=$?
18206         wait $DD_PID
18207         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18208         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18209
18210         # how many bytes copied before swapping layout
18211         local copied=$(stat -c %s $file2)
18212         local remaining=$(stat -c %s $ref1)
18213         remaining=$((remaining - copied))
18214         echo "Copied $copied bytes before swapping layout..."
18215
18216         cmp -n $copied $file1 $ref2 | grep differ &&
18217                 error "Content mismatch [0, $copied) of ref2 and file1"
18218         cmp -n $copied $file2 $ref1 ||
18219                 error "Content mismatch [0, $copied) of ref1 and file2"
18220         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18221                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18222
18223         # clean up
18224         rm -f $ref1 $ref2 $file1 $file2
18225 }
18226 run_test 184c "Concurrent write and layout swap"
18227
18228 test_184d() {
18229         check_swap_layouts_support
18230         check_swap_layout_no_dom $DIR
18231         [ -z "$(which getfattr 2>/dev/null)" ] &&
18232                 skip_env "no getfattr command"
18233
18234         local file1=$DIR/$tdir/$tfile-1
18235         local file2=$DIR/$tdir/$tfile-2
18236         local file3=$DIR/$tdir/$tfile-3
18237         local lovea1
18238         local lovea2
18239
18240         mkdir -p $DIR/$tdir
18241         touch $file1 || error "create $file1 failed"
18242         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18243                 error "create $file2 failed"
18244         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18245                 error "create $file3 failed"
18246         lovea1=$(get_layout_param $file1)
18247
18248         $LFS swap_layouts $file2 $file3 ||
18249                 error "swap $file2 $file3 layouts failed"
18250         $LFS swap_layouts $file1 $file2 ||
18251                 error "swap $file1 $file2 layouts failed"
18252
18253         lovea2=$(get_layout_param $file2)
18254         echo "$lovea1"
18255         echo "$lovea2"
18256         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18257
18258         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18259         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18260 }
18261 run_test 184d "allow stripeless layouts swap"
18262
18263 test_184e() {
18264         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18265                 skip "Need MDS version at least 2.6.94"
18266         check_swap_layouts_support
18267         check_swap_layout_no_dom $DIR
18268         [ -z "$(which getfattr 2>/dev/null)" ] &&
18269                 skip_env "no getfattr command"
18270
18271         local file1=$DIR/$tdir/$tfile-1
18272         local file2=$DIR/$tdir/$tfile-2
18273         local file3=$DIR/$tdir/$tfile-3
18274         local lovea
18275
18276         mkdir -p $DIR/$tdir
18277         touch $file1 || error "create $file1 failed"
18278         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18279                 error "create $file2 failed"
18280         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18281                 error "create $file3 failed"
18282
18283         $LFS swap_layouts $file1 $file2 ||
18284                 error "swap $file1 $file2 layouts failed"
18285
18286         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18287         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18288
18289         echo 123 > $file1 || error "Should be able to write into $file1"
18290
18291         $LFS swap_layouts $file1 $file3 ||
18292                 error "swap $file1 $file3 layouts failed"
18293
18294         echo 123 > $file1 || error "Should be able to write into $file1"
18295
18296         rm -rf $file1 $file2 $file3
18297 }
18298 run_test 184e "Recreate layout after stripeless layout swaps"
18299
18300 test_184f() {
18301         # Create a file with name longer than sizeof(struct stat) ==
18302         # 144 to see if we can get chars from the file name to appear
18303         # in the returned striping. Note that 'f' == 0x66.
18304         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18305
18306         mkdir -p $DIR/$tdir
18307         mcreate $DIR/$tdir/$file
18308         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18309                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18310         fi
18311 }
18312 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18313
18314 test_185() { # LU-2441
18315         # LU-3553 - no volatile file support in old servers
18316         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18317                 skip "Need MDS version at least 2.3.60"
18318
18319         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18320         touch $DIR/$tdir/spoo
18321         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18322         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18323                 error "cannot create/write a volatile file"
18324         [ "$FILESET" == "" ] &&
18325         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18326                 error "FID is still valid after close"
18327
18328         multiop_bg_pause $DIR/$tdir vVw4096_c
18329         local multi_pid=$!
18330
18331         local OLD_IFS=$IFS
18332         IFS=":"
18333         local fidv=($fid)
18334         IFS=$OLD_IFS
18335         # assume that the next FID for this client is sequential, since stdout
18336         # is unfortunately eaten by multiop_bg_pause
18337         local n=$((${fidv[1]} + 1))
18338         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18339         if [ "$FILESET" == "" ]; then
18340                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18341                         error "FID is missing before close"
18342         fi
18343         kill -USR1 $multi_pid
18344         # 1 second delay, so if mtime change we will see it
18345         sleep 1
18346         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18347         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18348 }
18349 run_test 185 "Volatile file support"
18350
18351 function create_check_volatile() {
18352         local idx=$1
18353         local tgt
18354
18355         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18356         local PID=$!
18357         sleep 1
18358         local FID=$(cat /tmp/${tfile}.fid)
18359         [ "$FID" == "" ] && error "can't get FID for volatile"
18360         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18361         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18362         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18363         kill -USR1 $PID
18364         wait
18365         sleep 1
18366         cancel_lru_locks mdc # flush opencache
18367         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18368         return 0
18369 }
18370
18371 test_185a(){
18372         # LU-12516 - volatile creation via .lustre
18373         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18374                 skip "Need MDS version at least 2.3.55"
18375
18376         create_check_volatile 0
18377         [ $MDSCOUNT -lt 2 ] && return 0
18378
18379         # DNE case
18380         create_check_volatile 1
18381
18382         return 0
18383 }
18384 run_test 185a "Volatile file creation in .lustre/fid/"
18385
18386 test_187a() {
18387         remote_mds_nodsh && skip "remote MDS with nodsh"
18388         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18389                 skip "Need MDS version at least 2.3.0"
18390
18391         local dir0=$DIR/$tdir/$testnum
18392         mkdir -p $dir0 || error "creating dir $dir0"
18393
18394         local file=$dir0/file1
18395         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18396         local dv1=$($LFS data_version $file)
18397         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18398         local dv2=$($LFS data_version $file)
18399         [[ $dv1 != $dv2 ]] ||
18400                 error "data version did not change on write $dv1 == $dv2"
18401
18402         # clean up
18403         rm -f $file1
18404 }
18405 run_test 187a "Test data version change"
18406
18407 test_187b() {
18408         remote_mds_nodsh && skip "remote MDS with nodsh"
18409         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18410                 skip "Need MDS version at least 2.3.0"
18411
18412         local dir0=$DIR/$tdir/$testnum
18413         mkdir -p $dir0 || error "creating dir $dir0"
18414
18415         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18416         [[ ${DV[0]} != ${DV[1]} ]] ||
18417                 error "data version did not change on write"\
18418                       " ${DV[0]} == ${DV[1]}"
18419
18420         # clean up
18421         rm -f $file1
18422 }
18423 run_test 187b "Test data version change on volatile file"
18424
18425 test_200() {
18426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18427         remote_mgs_nodsh && skip "remote MGS with nodsh"
18428         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18429
18430         local POOL=${POOL:-cea1}
18431         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18432         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18433         # Pool OST targets
18434         local first_ost=0
18435         local last_ost=$(($OSTCOUNT - 1))
18436         local ost_step=2
18437         local ost_list=$(seq $first_ost $ost_step $last_ost)
18438         local ost_range="$first_ost $last_ost $ost_step"
18439         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18440         local file_dir=$POOL_ROOT/file_tst
18441         local subdir=$test_path/subdir
18442         local rc=0
18443
18444         while : ; do
18445                 # former test_200a test_200b
18446                 pool_add $POOL                          || { rc=$? ; break; }
18447                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18448                 # former test_200c test_200d
18449                 mkdir -p $test_path
18450                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18451                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18452                 mkdir -p $subdir
18453                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18454                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18455                                                         || { rc=$? ; break; }
18456                 # former test_200e test_200f
18457                 local files=$((OSTCOUNT*3))
18458                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18459                                                         || { rc=$? ; break; }
18460                 pool_create_files $POOL $file_dir $files "$ost_list" \
18461                                                         || { rc=$? ; break; }
18462                 # former test_200g test_200h
18463                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18464                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18465
18466                 # former test_201a test_201b test_201c
18467                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18468
18469                 local f=$test_path/$tfile
18470                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18471                 pool_remove $POOL $f                    || { rc=$? ; break; }
18472                 break
18473         done
18474
18475         destroy_test_pools
18476
18477         return $rc
18478 }
18479 run_test 200 "OST pools"
18480
18481 # usage: default_attr <count | size | offset>
18482 default_attr() {
18483         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18484 }
18485
18486 # usage: check_default_stripe_attr
18487 check_default_stripe_attr() {
18488         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18489         case $1 in
18490         --stripe-count|-c)
18491                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18492         --stripe-size|-S)
18493                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18494         --stripe-index|-i)
18495                 EXPECTED=-1;;
18496         *)
18497                 error "unknown getstripe attr '$1'"
18498         esac
18499
18500         [ $ACTUAL == $EXPECTED ] ||
18501                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18502 }
18503
18504 test_204a() {
18505         test_mkdir $DIR/$tdir
18506         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18507
18508         check_default_stripe_attr --stripe-count
18509         check_default_stripe_attr --stripe-size
18510         check_default_stripe_attr --stripe-index
18511 }
18512 run_test 204a "Print default stripe attributes"
18513
18514 test_204b() {
18515         test_mkdir $DIR/$tdir
18516         $LFS setstripe --stripe-count 1 $DIR/$tdir
18517
18518         check_default_stripe_attr --stripe-size
18519         check_default_stripe_attr --stripe-index
18520 }
18521 run_test 204b "Print default stripe size and offset"
18522
18523 test_204c() {
18524         test_mkdir $DIR/$tdir
18525         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18526
18527         check_default_stripe_attr --stripe-count
18528         check_default_stripe_attr --stripe-index
18529 }
18530 run_test 204c "Print default stripe count and offset"
18531
18532 test_204d() {
18533         test_mkdir $DIR/$tdir
18534         $LFS setstripe --stripe-index 0 $DIR/$tdir
18535
18536         check_default_stripe_attr --stripe-count
18537         check_default_stripe_attr --stripe-size
18538 }
18539 run_test 204d "Print default stripe count and size"
18540
18541 test_204e() {
18542         test_mkdir $DIR/$tdir
18543         $LFS setstripe -d $DIR/$tdir
18544
18545         check_default_stripe_attr --stripe-count --raw
18546         check_default_stripe_attr --stripe-size --raw
18547         check_default_stripe_attr --stripe-index --raw
18548 }
18549 run_test 204e "Print raw stripe attributes"
18550
18551 test_204f() {
18552         test_mkdir $DIR/$tdir
18553         $LFS setstripe --stripe-count 1 $DIR/$tdir
18554
18555         check_default_stripe_attr --stripe-size --raw
18556         check_default_stripe_attr --stripe-index --raw
18557 }
18558 run_test 204f "Print raw stripe size and offset"
18559
18560 test_204g() {
18561         test_mkdir $DIR/$tdir
18562         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18563
18564         check_default_stripe_attr --stripe-count --raw
18565         check_default_stripe_attr --stripe-index --raw
18566 }
18567 run_test 204g "Print raw stripe count and offset"
18568
18569 test_204h() {
18570         test_mkdir $DIR/$tdir
18571         $LFS setstripe --stripe-index 0 $DIR/$tdir
18572
18573         check_default_stripe_attr --stripe-count --raw
18574         check_default_stripe_attr --stripe-size --raw
18575 }
18576 run_test 204h "Print raw stripe count and size"
18577
18578 # Figure out which job scheduler is being used, if any,
18579 # or use a fake one
18580 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18581         JOBENV=SLURM_JOB_ID
18582 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18583         JOBENV=LSB_JOBID
18584 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18585         JOBENV=PBS_JOBID
18586 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18587         JOBENV=LOADL_STEP_ID
18588 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18589         JOBENV=JOB_ID
18590 else
18591         $LCTL list_param jobid_name > /dev/null 2>&1
18592         if [ $? -eq 0 ]; then
18593                 JOBENV=nodelocal
18594         else
18595                 JOBENV=FAKE_JOBID
18596         fi
18597 fi
18598 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18599
18600 verify_jobstats() {
18601         local cmd=($1)
18602         shift
18603         local facets="$@"
18604
18605 # we don't really need to clear the stats for this test to work, since each
18606 # command has a unique jobid, but it makes debugging easier if needed.
18607 #       for facet in $facets; do
18608 #               local dev=$(convert_facet2label $facet)
18609 #               # clear old jobstats
18610 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18611 #       done
18612
18613         # use a new JobID for each test, or we might see an old one
18614         [ "$JOBENV" = "FAKE_JOBID" ] &&
18615                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18616
18617         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18618
18619         [ "$JOBENV" = "nodelocal" ] && {
18620                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18621                 $LCTL set_param jobid_name=$FAKE_JOBID
18622                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18623         }
18624
18625         log "Test: ${cmd[*]}"
18626         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18627
18628         if [ $JOBENV = "FAKE_JOBID" ]; then
18629                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18630         else
18631                 ${cmd[*]}
18632         fi
18633
18634         # all files are created on OST0000
18635         for facet in $facets; do
18636                 local stats="*.$(convert_facet2label $facet).job_stats"
18637
18638                 # strip out libtool wrappers for in-tree executables
18639                 if (( $(do_facet $facet lctl get_param $stats |
18640                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18641                         do_facet $facet lctl get_param $stats
18642                         error "No jobstats for $JOBVAL found on $facet::$stats"
18643                 fi
18644         done
18645 }
18646
18647 jobstats_set() {
18648         local new_jobenv=$1
18649
18650         set_persistent_param_and_check client "jobid_var" \
18651                 "$FSNAME.sys.jobid_var" $new_jobenv
18652 }
18653
18654 test_205a() { # Job stats
18655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18656         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18657                 skip "Need MDS version with at least 2.7.1"
18658         remote_mgs_nodsh && skip "remote MGS with nodsh"
18659         remote_mds_nodsh && skip "remote MDS with nodsh"
18660         remote_ost_nodsh && skip "remote OST with nodsh"
18661         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18662                 skip "Server doesn't support jobstats"
18663         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18664
18665         local old_jobenv=$($LCTL get_param -n jobid_var)
18666         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18667
18668         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18669                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18670         else
18671                 stack_trap "do_facet mgs $PERM_CMD \
18672                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18673         fi
18674         changelog_register
18675
18676         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18677                                 mdt.*.job_cleanup_interval | head -n 1)
18678         local new_interval=5
18679         do_facet $SINGLEMDS \
18680                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18681         stack_trap "do_facet $SINGLEMDS \
18682                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18683         local start=$SECONDS
18684
18685         local cmd
18686         # mkdir
18687         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18688         verify_jobstats "$cmd" "$SINGLEMDS"
18689         # rmdir
18690         cmd="rmdir $DIR/$tdir"
18691         verify_jobstats "$cmd" "$SINGLEMDS"
18692         # mkdir on secondary MDT
18693         if [ $MDSCOUNT -gt 1 ]; then
18694                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18695                 verify_jobstats "$cmd" "mds2"
18696         fi
18697         # mknod
18698         cmd="mknod $DIR/$tfile c 1 3"
18699         verify_jobstats "$cmd" "$SINGLEMDS"
18700         # unlink
18701         cmd="rm -f $DIR/$tfile"
18702         verify_jobstats "$cmd" "$SINGLEMDS"
18703         # create all files on OST0000 so verify_jobstats can find OST stats
18704         # open & close
18705         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18706         verify_jobstats "$cmd" "$SINGLEMDS"
18707         # setattr
18708         cmd="touch $DIR/$tfile"
18709         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18710         # write
18711         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18712         verify_jobstats "$cmd" "ost1"
18713         # read
18714         cancel_lru_locks osc
18715         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18716         verify_jobstats "$cmd" "ost1"
18717         # truncate
18718         cmd="$TRUNCATE $DIR/$tfile 0"
18719         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18720         # rename
18721         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18722         verify_jobstats "$cmd" "$SINGLEMDS"
18723         # jobstats expiry - sleep until old stats should be expired
18724         local left=$((new_interval + 5 - (SECONDS - start)))
18725         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18726                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18727                         "0" $left
18728         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18729         verify_jobstats "$cmd" "$SINGLEMDS"
18730         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18731             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18732
18733         # Ensure that jobid are present in changelog (if supported by MDS)
18734         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18735                 changelog_dump | tail -10
18736                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18737                 [ $jobids -eq 9 ] ||
18738                         error "Wrong changelog jobid count $jobids != 9"
18739
18740                 # LU-5862
18741                 JOBENV="disable"
18742                 jobstats_set $JOBENV
18743                 touch $DIR/$tfile
18744                 changelog_dump | grep $tfile
18745                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18746                 [ $jobids -eq 0 ] ||
18747                         error "Unexpected jobids when jobid_var=$JOBENV"
18748         fi
18749
18750         # test '%j' access to environment variable - if supported
18751         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18752                 JOBENV="JOBCOMPLEX"
18753                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18754
18755                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18756         fi
18757
18758         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18759                 JOBENV="JOBCOMPLEX"
18760                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18761
18762                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18763         fi
18764
18765         # test '%j' access to per-session jobid - if supported
18766         if lctl list_param jobid_this_session > /dev/null 2>&1
18767         then
18768                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18769                 lctl set_param jobid_this_session=$USER
18770
18771                 JOBENV="JOBCOMPLEX"
18772                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18773
18774                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18775         fi
18776 }
18777 run_test 205a "Verify job stats"
18778
18779 # LU-13117, LU-13597
18780 test_205b() {
18781         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18782                 skip "Need MDS version at least 2.13.54.91"
18783
18784         local job_stats="mdt.*.job_stats"
18785         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18786
18787         do_facet mds1 $LCTL set_param $job_stats=clear
18788
18789         # Setting jobid_var to USER might not be supported
18790         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18791         $LCTL set_param jobid_var=USER || true
18792         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18793         $LCTL set_param jobid_name="%j.%e.%u"
18794
18795         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18796         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18797                 { do_facet mds1 $LCTL get_param $job_stats;
18798                   error "Unexpected jobid found"; }
18799         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18800                 { do_facet mds1 $LCTL get_param $job_stats;
18801                   error "wrong job_stats format found"; }
18802
18803         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18804                 echo "MDS does not yet escape jobid" && return 0
18805         $LCTL set_param jobid_var=TEST205b
18806         env -i TEST205b="has sp" touch $DIR/$tfile.2
18807         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18808                 { do_facet mds1 $LCTL get_param $job_stats;
18809                   error "jobid not escaped"; }
18810 }
18811 run_test 205b "Verify job stats jobid and output format"
18812
18813 # LU-13733
18814 test_205c() {
18815         $LCTL set_param llite.*.stats=0
18816         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18817         $LCTL get_param llite.*.stats
18818         $LCTL get_param llite.*.stats | grep \
18819                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18820                         error "wrong client stats format found"
18821 }
18822 run_test 205c "Verify client stats format"
18823
18824 # LU-1480, LU-1773 and LU-1657
18825 test_206() {
18826         mkdir -p $DIR/$tdir
18827         $LFS setstripe -c -1 $DIR/$tdir
18828 #define OBD_FAIL_LOV_INIT 0x1403
18829         $LCTL set_param fail_loc=0xa0001403
18830         $LCTL set_param fail_val=1
18831         touch $DIR/$tdir/$tfile || true
18832 }
18833 run_test 206 "fail lov_init_raid0() doesn't lbug"
18834
18835 test_207a() {
18836         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18837         local fsz=`stat -c %s $DIR/$tfile`
18838         cancel_lru_locks mdc
18839
18840         # do not return layout in getattr intent
18841 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18842         $LCTL set_param fail_loc=0x170
18843         local sz=`stat -c %s $DIR/$tfile`
18844
18845         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18846
18847         rm -rf $DIR/$tfile
18848 }
18849 run_test 207a "can refresh layout at glimpse"
18850
18851 test_207b() {
18852         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18853         local cksum=`md5sum $DIR/$tfile`
18854         local fsz=`stat -c %s $DIR/$tfile`
18855         cancel_lru_locks mdc
18856         cancel_lru_locks osc
18857
18858         # do not return layout in getattr intent
18859 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18860         $LCTL set_param fail_loc=0x171
18861
18862         # it will refresh layout after the file is opened but before read issues
18863         echo checksum is "$cksum"
18864         echo "$cksum" |md5sum -c --quiet || error "file differs"
18865
18866         rm -rf $DIR/$tfile
18867 }
18868 run_test 207b "can refresh layout at open"
18869
18870 test_208() {
18871         # FIXME: in this test suite, only RD lease is used. This is okay
18872         # for now as only exclusive open is supported. After generic lease
18873         # is done, this test suite should be revised. - Jinshan
18874
18875         remote_mds_nodsh && skip "remote MDS with nodsh"
18876         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18877                 skip "Need MDS version at least 2.4.52"
18878
18879         echo "==== test 1: verify get lease work"
18880         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18881
18882         echo "==== test 2: verify lease can be broken by upcoming open"
18883         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18884         local PID=$!
18885         sleep 2
18886
18887         $MULTIOP $DIR/$tfile oO_RDWR:c
18888         kill -USR1 $PID && wait $PID || error "break lease error"
18889
18890         echo "==== test 3: verify lease can't be granted if an open already exists"
18891         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18892         local PID=$!
18893         sleep 2
18894
18895         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18896         kill -USR1 $PID && wait $PID || error "open file error"
18897
18898         echo "==== test 4: lease can sustain over recovery"
18899         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18900         PID=$!
18901         sleep 2
18902
18903         fail mds1
18904
18905         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18906
18907         echo "==== test 5: lease broken can't be regained by replay"
18908         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18909         PID=$!
18910         sleep 2
18911
18912         # open file to break lease and then recovery
18913         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18914         fail mds1
18915
18916         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18917
18918         rm -f $DIR/$tfile
18919 }
18920 run_test 208 "Exclusive open"
18921
18922 test_209() {
18923         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18924                 skip_env "must have disp_stripe"
18925
18926         touch $DIR/$tfile
18927         sync; sleep 5; sync;
18928
18929         echo 3 > /proc/sys/vm/drop_caches
18930         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18931                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18932         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18933
18934         # open/close 500 times
18935         for i in $(seq 500); do
18936                 cat $DIR/$tfile
18937         done
18938
18939         echo 3 > /proc/sys/vm/drop_caches
18940         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18941                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18942         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18943
18944         echo "before: $req_before, after: $req_after"
18945         [ $((req_after - req_before)) -ge 300 ] &&
18946                 error "open/close requests are not freed"
18947         return 0
18948 }
18949 run_test 209 "read-only open/close requests should be freed promptly"
18950
18951 test_210() {
18952         local pid
18953
18954         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18955         pid=$!
18956         sleep 1
18957
18958         $LFS getstripe $DIR/$tfile
18959         kill -USR1 $pid
18960         wait $pid || error "multiop failed"
18961
18962         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18963         pid=$!
18964         sleep 1
18965
18966         $LFS getstripe $DIR/$tfile
18967         kill -USR1 $pid
18968         wait $pid || error "multiop failed"
18969 }
18970 run_test 210 "lfs getstripe does not break leases"
18971
18972 test_212() {
18973         size=`date +%s`
18974         size=$((size % 8192 + 1))
18975         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18976         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18977         rm -f $DIR/f212 $DIR/f212.xyz
18978 }
18979 run_test 212 "Sendfile test ============================================"
18980
18981 test_213() {
18982         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18983         cancel_lru_locks osc
18984         lctl set_param fail_loc=0x8000040f
18985         # generate a read lock
18986         cat $DIR/$tfile > /dev/null
18987         # write to the file, it will try to cancel the above read lock.
18988         cat /etc/hosts >> $DIR/$tfile
18989 }
18990 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18991
18992 test_214() { # for bug 20133
18993         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18994         for (( i=0; i < 340; i++ )) ; do
18995                 touch $DIR/$tdir/d214c/a$i
18996         done
18997
18998         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18999         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19000         ls $DIR/d214c || error "ls $DIR/d214c failed"
19001         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19002         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19003 }
19004 run_test 214 "hash-indexed directory test - bug 20133"
19005
19006 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19007 create_lnet_proc_files() {
19008         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19009 }
19010
19011 # counterpart of create_lnet_proc_files
19012 remove_lnet_proc_files() {
19013         rm -f $TMP/lnet_$1.sys
19014 }
19015
19016 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19017 # 3rd arg as regexp for body
19018 check_lnet_proc_stats() {
19019         local l=$(cat "$TMP/lnet_$1" |wc -l)
19020         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19021
19022         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19023 }
19024
19025 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19026 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19027 # optional and can be regexp for 2nd line (lnet.routes case)
19028 check_lnet_proc_entry() {
19029         local blp=2          # blp stands for 'position of 1st line of body'
19030         [ -z "$5" ] || blp=3 # lnet.routes case
19031
19032         local l=$(cat "$TMP/lnet_$1" |wc -l)
19033         # subtracting one from $blp because the body can be empty
19034         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19035
19036         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19037                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19038
19039         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19040                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19041
19042         # bail out if any unexpected line happened
19043         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19044         [ "$?" != 0 ] || error "$2 misformatted"
19045 }
19046
19047 test_215() { # for bugs 18102, 21079, 21517
19048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19049
19050         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19051         local P='[1-9][0-9]*'           # positive numeric
19052         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19053         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19054         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19055         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19056
19057         local L1 # regexp for 1st line
19058         local L2 # regexp for 2nd line (optional)
19059         local BR # regexp for the rest (body)
19060
19061         # lnet.stats should look as 11 space-separated non-negative numerics
19062         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19063         create_lnet_proc_files "stats"
19064         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19065         remove_lnet_proc_files "stats"
19066
19067         # lnet.routes should look like this:
19068         # Routing disabled/enabled
19069         # net hops priority state router
19070         # where net is a string like tcp0, hops > 0, priority >= 0,
19071         # state is up/down,
19072         # router is a string like 192.168.1.1@tcp2
19073         L1="^Routing (disabled|enabled)$"
19074         L2="^net +hops +priority +state +router$"
19075         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19076         create_lnet_proc_files "routes"
19077         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19078         remove_lnet_proc_files "routes"
19079
19080         # lnet.routers should look like this:
19081         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19082         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19083         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19084         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19085         L1="^ref +rtr_ref +alive +router$"
19086         BR="^$P +$P +(up|down) +$NID$"
19087         create_lnet_proc_files "routers"
19088         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19089         remove_lnet_proc_files "routers"
19090
19091         # lnet.peers should look like this:
19092         # nid refs state last max rtr min tx min queue
19093         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19094         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19095         # numeric (0 or >0 or <0), queue >= 0.
19096         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19097         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19098         create_lnet_proc_files "peers"
19099         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19100         remove_lnet_proc_files "peers"
19101
19102         # lnet.buffers  should look like this:
19103         # pages count credits min
19104         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19105         L1="^pages +count +credits +min$"
19106         BR="^ +$N +$N +$I +$I$"
19107         create_lnet_proc_files "buffers"
19108         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19109         remove_lnet_proc_files "buffers"
19110
19111         # lnet.nis should look like this:
19112         # nid status alive refs peer rtr max tx min
19113         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19114         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19115         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19116         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19117         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19118         create_lnet_proc_files "nis"
19119         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19120         remove_lnet_proc_files "nis"
19121
19122         # can we successfully write to lnet.stats?
19123         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19124 }
19125 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19126
19127 test_216() { # bug 20317
19128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19129         remote_ost_nodsh && skip "remote OST with nodsh"
19130
19131         local node
19132         local facets=$(get_facets OST)
19133         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19134
19135         save_lustre_params client "osc.*.contention_seconds" > $p
19136         save_lustre_params $facets \
19137                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19138         save_lustre_params $facets \
19139                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19140         save_lustre_params $facets \
19141                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19142         clear_stats osc.*.osc_stats
19143
19144         # agressive lockless i/o settings
19145         do_nodes $(comma_list $(osts_nodes)) \
19146                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19147                         ldlm.namespaces.filter-*.contended_locks=0 \
19148                         ldlm.namespaces.filter-*.contention_seconds=60"
19149         lctl set_param -n osc.*.contention_seconds=60
19150
19151         $DIRECTIO write $DIR/$tfile 0 10 4096
19152         $CHECKSTAT -s 40960 $DIR/$tfile
19153
19154         # disable lockless i/o
19155         do_nodes $(comma_list $(osts_nodes)) \
19156                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19157                         ldlm.namespaces.filter-*.contended_locks=32 \
19158                         ldlm.namespaces.filter-*.contention_seconds=0"
19159         lctl set_param -n osc.*.contention_seconds=0
19160         clear_stats osc.*.osc_stats
19161
19162         dd if=/dev/zero of=$DIR/$tfile count=0
19163         $CHECKSTAT -s 0 $DIR/$tfile
19164
19165         restore_lustre_params <$p
19166         rm -f $p
19167         rm $DIR/$tfile
19168 }
19169 run_test 216 "check lockless direct write updates file size and kms correctly"
19170
19171 test_217() { # bug 22430
19172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19173
19174         local node
19175         local nid
19176
19177         for node in $(nodes_list); do
19178                 nid=$(host_nids_address $node $NETTYPE)
19179                 if [[ $nid = *-* ]] ; then
19180                         echo "lctl ping $(h2nettype $nid)"
19181                         lctl ping $(h2nettype $nid)
19182                 else
19183                         echo "skipping $node (no hyphen detected)"
19184                 fi
19185         done
19186 }
19187 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19188
19189 test_218() {
19190        # do directio so as not to populate the page cache
19191        log "creating a 10 Mb file"
19192        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19193        log "starting reads"
19194        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19195        log "truncating the file"
19196        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19197        log "killing dd"
19198        kill %+ || true # reads might have finished
19199        echo "wait until dd is finished"
19200        wait
19201        log "removing the temporary file"
19202        rm -rf $DIR/$tfile || error "tmp file removal failed"
19203 }
19204 run_test 218 "parallel read and truncate should not deadlock"
19205
19206 test_219() {
19207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19208
19209         # write one partial page
19210         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19211         # set no grant so vvp_io_commit_write will do sync write
19212         $LCTL set_param fail_loc=0x411
19213         # write a full page at the end of file
19214         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19215
19216         $LCTL set_param fail_loc=0
19217         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19218         $LCTL set_param fail_loc=0x411
19219         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19220
19221         # LU-4201
19222         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19223         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19224 }
19225 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19226
19227 test_220() { #LU-325
19228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19229         remote_ost_nodsh && skip "remote OST with nodsh"
19230         remote_mds_nodsh && skip "remote MDS with nodsh"
19231         remote_mgs_nodsh && skip "remote MGS with nodsh"
19232
19233         local OSTIDX=0
19234
19235         # create on MDT0000 so the last_id and next_id are correct
19236         mkdir_on_mdt0 $DIR/$tdir
19237         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19238         OST=${OST%_UUID}
19239
19240         # on the mdt's osc
19241         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19242         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19243                         osp.$mdtosc_proc1.prealloc_last_id)
19244         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19245                         osp.$mdtosc_proc1.prealloc_next_id)
19246
19247         $LFS df -i
19248
19249         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19250         #define OBD_FAIL_OST_ENOINO              0x229
19251         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19252         create_pool $FSNAME.$TESTNAME || return 1
19253         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19254
19255         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19256
19257         MDSOBJS=$((last_id - next_id))
19258         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19259
19260         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19261         echo "OST still has $count kbytes free"
19262
19263         echo "create $MDSOBJS files @next_id..."
19264         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19265
19266         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19267                         osp.$mdtosc_proc1.prealloc_last_id)
19268         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19269                         osp.$mdtosc_proc1.prealloc_next_id)
19270
19271         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19272         $LFS df -i
19273
19274         echo "cleanup..."
19275
19276         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19277         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19278
19279         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19280                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19281         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19282                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19283         echo "unlink $MDSOBJS files @$next_id..."
19284         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19285 }
19286 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19287
19288 test_221() {
19289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19290
19291         dd if=`which date` of=$MOUNT/date oflag=sync
19292         chmod +x $MOUNT/date
19293
19294         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19295         $LCTL set_param fail_loc=0x80001401
19296
19297         $MOUNT/date > /dev/null
19298         rm -f $MOUNT/date
19299 }
19300 run_test 221 "make sure fault and truncate race to not cause OOM"
19301
19302 test_222a () {
19303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19304
19305         rm -rf $DIR/$tdir
19306         test_mkdir $DIR/$tdir
19307         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19308         createmany -o $DIR/$tdir/$tfile 10
19309         cancel_lru_locks mdc
19310         cancel_lru_locks osc
19311         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19312         $LCTL set_param fail_loc=0x31a
19313         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19314         $LCTL set_param fail_loc=0
19315         rm -r $DIR/$tdir
19316 }
19317 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19318
19319 test_222b () {
19320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19321
19322         rm -rf $DIR/$tdir
19323         test_mkdir $DIR/$tdir
19324         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19325         createmany -o $DIR/$tdir/$tfile 10
19326         cancel_lru_locks mdc
19327         cancel_lru_locks osc
19328         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19329         $LCTL set_param fail_loc=0x31a
19330         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19331         $LCTL set_param fail_loc=0
19332 }
19333 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19334
19335 test_223 () {
19336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19337
19338         rm -rf $DIR/$tdir
19339         test_mkdir $DIR/$tdir
19340         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19341         createmany -o $DIR/$tdir/$tfile 10
19342         cancel_lru_locks mdc
19343         cancel_lru_locks osc
19344         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19345         $LCTL set_param fail_loc=0x31b
19346         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19347         $LCTL set_param fail_loc=0
19348         rm -r $DIR/$tdir
19349 }
19350 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19351
19352 test_224a() { # LU-1039, MRP-303
19353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19354         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19355         $LCTL set_param fail_loc=0x508
19356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19357         $LCTL set_param fail_loc=0
19358         df $DIR
19359 }
19360 run_test 224a "Don't panic on bulk IO failure"
19361
19362 test_224bd_sub() { # LU-1039, MRP-303
19363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19364         local timeout=$1
19365
19366         shift
19367         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19368
19369         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19370
19371         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19372         cancel_lru_locks osc
19373         set_checksums 0
19374         stack_trap "set_checksums $ORIG_CSUM" EXIT
19375         local at_max_saved=0
19376
19377         # adaptive timeouts may prevent seeing the issue
19378         if at_is_enabled; then
19379                 at_max_saved=$(at_max_get mds)
19380                 at_max_set 0 mds client
19381                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19382         fi
19383
19384         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19385         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19386         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19387
19388         do_facet ost1 $LCTL set_param fail_loc=0
19389         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19390         df $DIR
19391 }
19392
19393 test_224b() {
19394         test_224bd_sub 3 error "dd failed"
19395 }
19396 run_test 224b "Don't panic on bulk IO failure"
19397
19398 test_224c() { # LU-6441
19399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19400         remote_mds_nodsh && skip "remote MDS with nodsh"
19401
19402         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19403         save_writethrough $p
19404         set_cache writethrough on
19405
19406         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19407         local at_max=$($LCTL get_param -n at_max)
19408         local timeout=$($LCTL get_param -n timeout)
19409         local test_at="at_max"
19410         local param_at="$FSNAME.sys.at_max"
19411         local test_timeout="timeout"
19412         local param_timeout="$FSNAME.sys.timeout"
19413
19414         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19415
19416         set_persistent_param_and_check client "$test_at" "$param_at" 0
19417         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19418
19419         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19420         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19421         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19422         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19423         sync
19424         do_facet ost1 "$LCTL set_param fail_loc=0"
19425
19426         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19427         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19428                 $timeout
19429
19430         $LCTL set_param -n $pages_per_rpc
19431         restore_lustre_params < $p
19432         rm -f $p
19433 }
19434 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19435
19436 test_224d() { # LU-11169
19437         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19438 }
19439 run_test 224d "Don't corrupt data on bulk IO timeout"
19440
19441 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19442 test_225a () {
19443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19444         if [ -z ${MDSSURVEY} ]; then
19445                 skip_env "mds-survey not found"
19446         fi
19447         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19448                 skip "Need MDS version at least 2.2.51"
19449
19450         local mds=$(facet_host $SINGLEMDS)
19451         local target=$(do_nodes $mds 'lctl dl' |
19452                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19453
19454         local cmd1="file_count=1000 thrhi=4"
19455         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19456         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19457         local cmd="$cmd1 $cmd2 $cmd3"
19458
19459         rm -f ${TMP}/mds_survey*
19460         echo + $cmd
19461         eval $cmd || error "mds-survey with zero-stripe failed"
19462         cat ${TMP}/mds_survey*
19463         rm -f ${TMP}/mds_survey*
19464 }
19465 run_test 225a "Metadata survey sanity with zero-stripe"
19466
19467 test_225b () {
19468         if [ -z ${MDSSURVEY} ]; then
19469                 skip_env "mds-survey not found"
19470         fi
19471         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19472                 skip "Need MDS version at least 2.2.51"
19473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19474         remote_mds_nodsh && skip "remote MDS with nodsh"
19475         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19476                 skip_env "Need to mount OST to test"
19477         fi
19478
19479         local mds=$(facet_host $SINGLEMDS)
19480         local target=$(do_nodes $mds 'lctl dl' |
19481                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19482
19483         local cmd1="file_count=1000 thrhi=4"
19484         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19485         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19486         local cmd="$cmd1 $cmd2 $cmd3"
19487
19488         rm -f ${TMP}/mds_survey*
19489         echo + $cmd
19490         eval $cmd || error "mds-survey with stripe_count failed"
19491         cat ${TMP}/mds_survey*
19492         rm -f ${TMP}/mds_survey*
19493 }
19494 run_test 225b "Metadata survey sanity with stripe_count = 1"
19495
19496 mcreate_path2fid () {
19497         local mode=$1
19498         local major=$2
19499         local minor=$3
19500         local name=$4
19501         local desc=$5
19502         local path=$DIR/$tdir/$name
19503         local fid
19504         local rc
19505         local fid_path
19506
19507         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19508                 error "cannot create $desc"
19509
19510         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19511         rc=$?
19512         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19513
19514         fid_path=$($LFS fid2path $MOUNT $fid)
19515         rc=$?
19516         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19517
19518         [ "$path" == "$fid_path" ] ||
19519                 error "fid2path returned $fid_path, expected $path"
19520
19521         echo "pass with $path and $fid"
19522 }
19523
19524 test_226a () {
19525         rm -rf $DIR/$tdir
19526         mkdir -p $DIR/$tdir
19527
19528         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19529         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19530         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19531         mcreate_path2fid 0040666 0 0 dir "directory"
19532         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19533         mcreate_path2fid 0100666 0 0 file "regular file"
19534         mcreate_path2fid 0120666 0 0 link "symbolic link"
19535         mcreate_path2fid 0140666 0 0 sock "socket"
19536 }
19537 run_test 226a "call path2fid and fid2path on files of all type"
19538
19539 test_226b () {
19540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19541
19542         local MDTIDX=1
19543
19544         rm -rf $DIR/$tdir
19545         mkdir -p $DIR/$tdir
19546         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19547                 error "create remote directory failed"
19548         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19549         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19550                                 "character special file (null)"
19551         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19552                                 "character special file (no device)"
19553         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19554         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19555                                 "block special file (loop)"
19556         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19557         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19558         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19559 }
19560 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19561
19562 test_226c () {
19563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19564         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19565                 skip "Need MDS version at least 2.13.55"
19566
19567         local submnt=/mnt/submnt
19568         local srcfile=/etc/passwd
19569         local dstfile=$submnt/passwd
19570         local path
19571         local fid
19572
19573         rm -rf $DIR/$tdir
19574         rm -rf $submnt
19575         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19576                 error "create remote directory failed"
19577         mkdir -p $submnt || error "create $submnt failed"
19578         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19579                 error "mount $submnt failed"
19580         stack_trap "umount $submnt" EXIT
19581
19582         cp $srcfile $dstfile
19583         fid=$($LFS path2fid $dstfile)
19584         path=$($LFS fid2path $submnt "$fid")
19585         [ "$path" = "$dstfile" ] ||
19586                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19587 }
19588 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19589
19590 # LU-1299 Executing or running ldd on a truncated executable does not
19591 # cause an out-of-memory condition.
19592 test_227() {
19593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19594         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19595
19596         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19597         chmod +x $MOUNT/date
19598
19599         $MOUNT/date > /dev/null
19600         ldd $MOUNT/date > /dev/null
19601         rm -f $MOUNT/date
19602 }
19603 run_test 227 "running truncated executable does not cause OOM"
19604
19605 # LU-1512 try to reuse idle OI blocks
19606 test_228a() {
19607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19608         remote_mds_nodsh && skip "remote MDS with nodsh"
19609         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19610
19611         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19612         local myDIR=$DIR/$tdir
19613
19614         mkdir -p $myDIR
19615         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19616         $LCTL set_param fail_loc=0x80001002
19617         createmany -o $myDIR/t- 10000
19618         $LCTL set_param fail_loc=0
19619         # The guard is current the largest FID holder
19620         touch $myDIR/guard
19621         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19622                     tr -d '[')
19623         local IDX=$(($SEQ % 64))
19624
19625         do_facet $SINGLEMDS sync
19626         # Make sure journal flushed.
19627         sleep 6
19628         local blk1=$(do_facet $SINGLEMDS \
19629                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19630                      grep Blockcount | awk '{print $4}')
19631
19632         # Remove old files, some OI blocks will become idle.
19633         unlinkmany $myDIR/t- 10000
19634         # Create new files, idle OI blocks should be reused.
19635         createmany -o $myDIR/t- 2000
19636         do_facet $SINGLEMDS sync
19637         # Make sure journal flushed.
19638         sleep 6
19639         local blk2=$(do_facet $SINGLEMDS \
19640                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19641                      grep Blockcount | awk '{print $4}')
19642
19643         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19644 }
19645 run_test 228a "try to reuse idle OI blocks"
19646
19647 test_228b() {
19648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19649         remote_mds_nodsh && skip "remote MDS with nodsh"
19650         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19651
19652         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19653         local myDIR=$DIR/$tdir
19654
19655         mkdir -p $myDIR
19656         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19657         $LCTL set_param fail_loc=0x80001002
19658         createmany -o $myDIR/t- 10000
19659         $LCTL set_param fail_loc=0
19660         # The guard is current the largest FID holder
19661         touch $myDIR/guard
19662         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19663                     tr -d '[')
19664         local IDX=$(($SEQ % 64))
19665
19666         do_facet $SINGLEMDS sync
19667         # Make sure journal flushed.
19668         sleep 6
19669         local blk1=$(do_facet $SINGLEMDS \
19670                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19671                      grep Blockcount | awk '{print $4}')
19672
19673         # Remove old files, some OI blocks will become idle.
19674         unlinkmany $myDIR/t- 10000
19675
19676         # stop the MDT
19677         stop $SINGLEMDS || error "Fail to stop MDT."
19678         # remount the MDT
19679         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19680                 error "Fail to start MDT."
19681
19682         df $MOUNT || error "Fail to df."
19683         # Create new files, idle OI blocks should be reused.
19684         createmany -o $myDIR/t- 2000
19685         do_facet $SINGLEMDS sync
19686         # Make sure journal flushed.
19687         sleep 6
19688         local blk2=$(do_facet $SINGLEMDS \
19689                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19690                      grep Blockcount | awk '{print $4}')
19691
19692         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19693 }
19694 run_test 228b "idle OI blocks can be reused after MDT restart"
19695
19696 #LU-1881
19697 test_228c() {
19698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19699         remote_mds_nodsh && skip "remote MDS with nodsh"
19700         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19701
19702         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19703         local myDIR=$DIR/$tdir
19704
19705         mkdir -p $myDIR
19706         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19707         $LCTL set_param fail_loc=0x80001002
19708         # 20000 files can guarantee there are index nodes in the OI file
19709         createmany -o $myDIR/t- 20000
19710         $LCTL set_param fail_loc=0
19711         # The guard is current the largest FID holder
19712         touch $myDIR/guard
19713         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19714                     tr -d '[')
19715         local IDX=$(($SEQ % 64))
19716
19717         do_facet $SINGLEMDS sync
19718         # Make sure journal flushed.
19719         sleep 6
19720         local blk1=$(do_facet $SINGLEMDS \
19721                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19722                      grep Blockcount | awk '{print $4}')
19723
19724         # Remove old files, some OI blocks will become idle.
19725         unlinkmany $myDIR/t- 20000
19726         rm -f $myDIR/guard
19727         # The OI file should become empty now
19728
19729         # Create new files, idle OI blocks should be reused.
19730         createmany -o $myDIR/t- 2000
19731         do_facet $SINGLEMDS sync
19732         # Make sure journal flushed.
19733         sleep 6
19734         local blk2=$(do_facet $SINGLEMDS \
19735                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19736                      grep Blockcount | awk '{print $4}')
19737
19738         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19739 }
19740 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19741
19742 test_229() { # LU-2482, LU-3448
19743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19744         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19745         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19746                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19747
19748         rm -f $DIR/$tfile
19749
19750         # Create a file with a released layout and stripe count 2.
19751         $MULTIOP $DIR/$tfile H2c ||
19752                 error "failed to create file with released layout"
19753
19754         $LFS getstripe -v $DIR/$tfile
19755
19756         local pattern=$($LFS getstripe -L $DIR/$tfile)
19757         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19758
19759         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19760                 error "getstripe"
19761         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19762         stat $DIR/$tfile || error "failed to stat released file"
19763
19764         chown $RUNAS_ID $DIR/$tfile ||
19765                 error "chown $RUNAS_ID $DIR/$tfile failed"
19766
19767         chgrp $RUNAS_ID $DIR/$tfile ||
19768                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19769
19770         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19771         rm $DIR/$tfile || error "failed to remove released file"
19772 }
19773 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19774
19775 test_230a() {
19776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19777         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19778         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19779                 skip "Need MDS version at least 2.11.52"
19780
19781         local MDTIDX=1
19782
19783         test_mkdir $DIR/$tdir
19784         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19785         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19786         [ $mdt_idx -ne 0 ] &&
19787                 error "create local directory on wrong MDT $mdt_idx"
19788
19789         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19790                         error "create remote directory failed"
19791         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19792         [ $mdt_idx -ne $MDTIDX ] &&
19793                 error "create remote directory on wrong MDT $mdt_idx"
19794
19795         createmany -o $DIR/$tdir/test_230/t- 10 ||
19796                 error "create files on remote directory failed"
19797         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19798         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19799         rm -r $DIR/$tdir || error "unlink remote directory failed"
19800 }
19801 run_test 230a "Create remote directory and files under the remote directory"
19802
19803 test_230b() {
19804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19806         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19807                 skip "Need MDS version at least 2.11.52"
19808
19809         local MDTIDX=1
19810         local mdt_index
19811         local i
19812         local file
19813         local pid
19814         local stripe_count
19815         local migrate_dir=$DIR/$tdir/migrate_dir
19816         local other_dir=$DIR/$tdir/other_dir
19817
19818         test_mkdir $DIR/$tdir
19819         test_mkdir -i0 -c1 $migrate_dir
19820         test_mkdir -i0 -c1 $other_dir
19821         for ((i=0; i<10; i++)); do
19822                 mkdir -p $migrate_dir/dir_${i}
19823                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19824                         error "create files under remote dir failed $i"
19825         done
19826
19827         cp /etc/passwd $migrate_dir/$tfile
19828         cp /etc/passwd $other_dir/$tfile
19829         chattr +SAD $migrate_dir
19830         chattr +SAD $migrate_dir/$tfile
19831
19832         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19833         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19834         local old_dir_mode=$(stat -c%f $migrate_dir)
19835         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19836
19837         mkdir -p $migrate_dir/dir_default_stripe2
19838         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19839         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19840
19841         mkdir -p $other_dir
19842         ln $migrate_dir/$tfile $other_dir/luna
19843         ln $migrate_dir/$tfile $migrate_dir/sofia
19844         ln $other_dir/$tfile $migrate_dir/david
19845         ln -s $migrate_dir/$tfile $other_dir/zachary
19846         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19847         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19848
19849         local len
19850         local lnktgt
19851
19852         # inline symlink
19853         for len in 58 59 60; do
19854                 lnktgt=$(str_repeat 'l' $len)
19855                 touch $migrate_dir/$lnktgt
19856                 ln -s $lnktgt $migrate_dir/${len}char_ln
19857         done
19858
19859         # PATH_MAX
19860         for len in 4094 4095; do
19861                 lnktgt=$(str_repeat 'l' $len)
19862                 ln -s $lnktgt $migrate_dir/${len}char_ln
19863         done
19864
19865         # NAME_MAX
19866         for len in 254 255; do
19867                 touch $migrate_dir/$(str_repeat 'l' $len)
19868         done
19869
19870         $LFS migrate -m $MDTIDX $migrate_dir ||
19871                 error "fails on migrating remote dir to MDT1"
19872
19873         echo "migratate to MDT1, then checking.."
19874         for ((i = 0; i < 10; i++)); do
19875                 for file in $(find $migrate_dir/dir_${i}); do
19876                         mdt_index=$($LFS getstripe -m $file)
19877                         # broken symlink getstripe will fail
19878                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19879                                 error "$file is not on MDT${MDTIDX}"
19880                 done
19881         done
19882
19883         # the multiple link file should still in MDT0
19884         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19885         [ $mdt_index == 0 ] ||
19886                 error "$file is not on MDT${MDTIDX}"
19887
19888         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19889         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19890                 error " expect $old_dir_flag get $new_dir_flag"
19891
19892         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19893         [ "$old_file_flag" = "$new_file_flag" ] ||
19894                 error " expect $old_file_flag get $new_file_flag"
19895
19896         local new_dir_mode=$(stat -c%f $migrate_dir)
19897         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19898                 error "expect mode $old_dir_mode get $new_dir_mode"
19899
19900         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19901         [ "$old_file_mode" = "$new_file_mode" ] ||
19902                 error "expect mode $old_file_mode get $new_file_mode"
19903
19904         diff /etc/passwd $migrate_dir/$tfile ||
19905                 error "$tfile different after migration"
19906
19907         diff /etc/passwd $other_dir/luna ||
19908                 error "luna different after migration"
19909
19910         diff /etc/passwd $migrate_dir/sofia ||
19911                 error "sofia different after migration"
19912
19913         diff /etc/passwd $migrate_dir/david ||
19914                 error "david different after migration"
19915
19916         diff /etc/passwd $other_dir/zachary ||
19917                 error "zachary different after migration"
19918
19919         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19920                 error "${tfile}_ln different after migration"
19921
19922         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19923                 error "${tfile}_ln_other different after migration"
19924
19925         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19926         [ $stripe_count = 2 ] ||
19927                 error "dir strpe_count $d != 2 after migration."
19928
19929         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19930         [ $stripe_count = 2 ] ||
19931                 error "file strpe_count $d != 2 after migration."
19932
19933         #migrate back to MDT0
19934         MDTIDX=0
19935
19936         $LFS migrate -m $MDTIDX $migrate_dir ||
19937                 error "fails on migrating remote dir to MDT0"
19938
19939         echo "migrate back to MDT0, checking.."
19940         for file in $(find $migrate_dir); do
19941                 mdt_index=$($LFS getstripe -m $file)
19942                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19943                         error "$file is not on MDT${MDTIDX}"
19944         done
19945
19946         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19947         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19948                 error " expect $old_dir_flag get $new_dir_flag"
19949
19950         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19951         [ "$old_file_flag" = "$new_file_flag" ] ||
19952                 error " expect $old_file_flag get $new_file_flag"
19953
19954         local new_dir_mode=$(stat -c%f $migrate_dir)
19955         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19956                 error "expect mode $old_dir_mode get $new_dir_mode"
19957
19958         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19959         [ "$old_file_mode" = "$new_file_mode" ] ||
19960                 error "expect mode $old_file_mode get $new_file_mode"
19961
19962         diff /etc/passwd ${migrate_dir}/$tfile ||
19963                 error "$tfile different after migration"
19964
19965         diff /etc/passwd ${other_dir}/luna ||
19966                 error "luna different after migration"
19967
19968         diff /etc/passwd ${migrate_dir}/sofia ||
19969                 error "sofia different after migration"
19970
19971         diff /etc/passwd ${other_dir}/zachary ||
19972                 error "zachary different after migration"
19973
19974         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19975                 error "${tfile}_ln different after migration"
19976
19977         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19978                 error "${tfile}_ln_other different after migration"
19979
19980         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19981         [ $stripe_count = 2 ] ||
19982                 error "dir strpe_count $d != 2 after migration."
19983
19984         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19985         [ $stripe_count = 2 ] ||
19986                 error "file strpe_count $d != 2 after migration."
19987
19988         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19989 }
19990 run_test 230b "migrate directory"
19991
19992 test_230c() {
19993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19995         remote_mds_nodsh && skip "remote MDS with nodsh"
19996         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19997                 skip "Need MDS version at least 2.11.52"
19998
19999         local MDTIDX=1
20000         local total=3
20001         local mdt_index
20002         local file
20003         local migrate_dir=$DIR/$tdir/migrate_dir
20004
20005         #If migrating directory fails in the middle, all entries of
20006         #the directory is still accessiable.
20007         test_mkdir $DIR/$tdir
20008         test_mkdir -i0 -c1 $migrate_dir
20009         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20010         stat $migrate_dir
20011         createmany -o $migrate_dir/f $total ||
20012                 error "create files under ${migrate_dir} failed"
20013
20014         # fail after migrating top dir, and this will fail only once, so the
20015         # first sub file migration will fail (currently f3), others succeed.
20016         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20017         do_facet mds1 lctl set_param fail_loc=0x1801
20018         local t=$(ls $migrate_dir | wc -l)
20019         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20020                 error "migrate should fail"
20021         local u=$(ls $migrate_dir | wc -l)
20022         [ "$u" == "$t" ] || error "$u != $t during migration"
20023
20024         # add new dir/file should succeed
20025         mkdir $migrate_dir/dir ||
20026                 error "mkdir failed under migrating directory"
20027         touch $migrate_dir/file ||
20028                 error "create file failed under migrating directory"
20029
20030         # add file with existing name should fail
20031         for file in $migrate_dir/f*; do
20032                 stat $file > /dev/null || error "stat $file failed"
20033                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20034                         error "open(O_CREAT|O_EXCL) $file should fail"
20035                 $MULTIOP $file m && error "create $file should fail"
20036                 touch $DIR/$tdir/remote_dir/$tfile ||
20037                         error "touch $tfile failed"
20038                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20039                         error "link $file should fail"
20040                 mdt_index=$($LFS getstripe -m $file)
20041                 if [ $mdt_index == 0 ]; then
20042                         # file failed to migrate is not allowed to rename to
20043                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20044                                 error "rename to $file should fail"
20045                 else
20046                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20047                                 error "rename to $file failed"
20048                 fi
20049                 echo hello >> $file || error "write $file failed"
20050         done
20051
20052         # resume migration with different options should fail
20053         $LFS migrate -m 0 $migrate_dir &&
20054                 error "migrate -m 0 $migrate_dir should fail"
20055
20056         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20057                 error "migrate -c 2 $migrate_dir should fail"
20058
20059         # resume migration should succeed
20060         $LFS migrate -m $MDTIDX $migrate_dir ||
20061                 error "migrate $migrate_dir failed"
20062
20063         echo "Finish migration, then checking.."
20064         for file in $(find $migrate_dir); do
20065                 mdt_index=$($LFS getstripe -m $file)
20066                 [ $mdt_index == $MDTIDX ] ||
20067                         error "$file is not on MDT${MDTIDX}"
20068         done
20069
20070         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20071 }
20072 run_test 230c "check directory accessiblity if migration failed"
20073
20074 test_230d() {
20075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20077         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20078                 skip "Need MDS version at least 2.11.52"
20079         # LU-11235
20080         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20081
20082         local migrate_dir=$DIR/$tdir/migrate_dir
20083         local old_index
20084         local new_index
20085         local old_count
20086         local new_count
20087         local new_hash
20088         local mdt_index
20089         local i
20090         local j
20091
20092         old_index=$((RANDOM % MDSCOUNT))
20093         old_count=$((MDSCOUNT - old_index))
20094         new_index=$((RANDOM % MDSCOUNT))
20095         new_count=$((MDSCOUNT - new_index))
20096         new_hash=1 # for all_char
20097
20098         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20099         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20100
20101         test_mkdir $DIR/$tdir
20102         test_mkdir -i $old_index -c $old_count $migrate_dir
20103
20104         for ((i=0; i<100; i++)); do
20105                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20106                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20107                         error "create files under remote dir failed $i"
20108         done
20109
20110         echo -n "Migrate from MDT$old_index "
20111         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20112         echo -n "to MDT$new_index"
20113         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20114         echo
20115
20116         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20117         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20118                 error "migrate remote dir error"
20119
20120         echo "Finish migration, then checking.."
20121         for file in $(find $migrate_dir -maxdepth 1); do
20122                 mdt_index=$($LFS getstripe -m $file)
20123                 if [ $mdt_index -lt $new_index ] ||
20124                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20125                         error "$file is on MDT$mdt_index"
20126                 fi
20127         done
20128
20129         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20130 }
20131 run_test 230d "check migrate big directory"
20132
20133 test_230e() {
20134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20137                 skip "Need MDS version at least 2.11.52"
20138
20139         local i
20140         local j
20141         local a_fid
20142         local b_fid
20143
20144         mkdir_on_mdt0 $DIR/$tdir
20145         mkdir $DIR/$tdir/migrate_dir
20146         mkdir $DIR/$tdir/other_dir
20147         touch $DIR/$tdir/migrate_dir/a
20148         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20149         ls $DIR/$tdir/other_dir
20150
20151         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20152                 error "migrate dir fails"
20153
20154         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20155         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20156
20157         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20158         [ $mdt_index == 0 ] || error "a is not on MDT0"
20159
20160         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20161                 error "migrate dir fails"
20162
20163         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20164         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20165
20166         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20167         [ $mdt_index == 1 ] || error "a is not on MDT1"
20168
20169         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20170         [ $mdt_index == 1 ] || error "b is not on MDT1"
20171
20172         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20173         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20174
20175         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20176
20177         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20178 }
20179 run_test 230e "migrate mulitple local link files"
20180
20181 test_230f() {
20182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20184         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20185                 skip "Need MDS version at least 2.11.52"
20186
20187         local a_fid
20188         local ln_fid
20189
20190         mkdir -p $DIR/$tdir
20191         mkdir $DIR/$tdir/migrate_dir
20192         $LFS mkdir -i1 $DIR/$tdir/other_dir
20193         touch $DIR/$tdir/migrate_dir/a
20194         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20195         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20196         ls $DIR/$tdir/other_dir
20197
20198         # a should be migrated to MDT1, since no other links on MDT0
20199         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20200                 error "#1 migrate dir fails"
20201         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20202         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20203         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20204         [ $mdt_index == 1 ] || error "a is not on MDT1"
20205
20206         # a should stay on MDT1, because it is a mulitple link file
20207         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20208                 error "#2 migrate dir fails"
20209         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20210         [ $mdt_index == 1 ] || error "a is not on MDT1"
20211
20212         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20213                 error "#3 migrate dir fails"
20214
20215         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20216         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20217         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20218
20219         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20220         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20221
20222         # a should be migrated to MDT0, since no other links on MDT1
20223         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20224                 error "#4 migrate dir fails"
20225         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20226         [ $mdt_index == 0 ] || error "a is not on MDT0"
20227
20228         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20229 }
20230 run_test 230f "migrate mulitple remote link files"
20231
20232 test_230g() {
20233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20235         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20236                 skip "Need MDS version at least 2.11.52"
20237
20238         mkdir -p $DIR/$tdir/migrate_dir
20239
20240         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20241                 error "migrating dir to non-exist MDT succeeds"
20242         true
20243 }
20244 run_test 230g "migrate dir to non-exist MDT"
20245
20246 test_230h() {
20247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20250                 skip "Need MDS version at least 2.11.52"
20251
20252         local mdt_index
20253
20254         mkdir -p $DIR/$tdir/migrate_dir
20255
20256         $LFS migrate -m1 $DIR &&
20257                 error "migrating mountpoint1 should fail"
20258
20259         $LFS migrate -m1 $DIR/$tdir/.. &&
20260                 error "migrating mountpoint2 should fail"
20261
20262         # same as mv
20263         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20264                 error "migrating $tdir/migrate_dir/.. should fail"
20265
20266         true
20267 }
20268 run_test 230h "migrate .. and root"
20269
20270 test_230i() {
20271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20273         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20274                 skip "Need MDS version at least 2.11.52"
20275
20276         mkdir -p $DIR/$tdir/migrate_dir
20277
20278         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20279                 error "migration fails with a tailing slash"
20280
20281         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20282                 error "migration fails with two tailing slashes"
20283 }
20284 run_test 230i "lfs migrate -m tolerates trailing slashes"
20285
20286 test_230j() {
20287         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20288         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20289                 skip "Need MDS version at least 2.11.52"
20290
20291         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20292         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20293                 error "create $tfile failed"
20294         cat /etc/passwd > $DIR/$tdir/$tfile
20295
20296         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20297
20298         cmp /etc/passwd $DIR/$tdir/$tfile ||
20299                 error "DoM file mismatch after migration"
20300 }
20301 run_test 230j "DoM file data not changed after dir migration"
20302
20303 test_230k() {
20304         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20305         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20306                 skip "Need MDS version at least 2.11.56"
20307
20308         local total=20
20309         local files_on_starting_mdt=0
20310
20311         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20312         $LFS getdirstripe $DIR/$tdir
20313         for i in $(seq $total); do
20314                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20315                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20316                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20317         done
20318
20319         echo "$files_on_starting_mdt files on MDT0"
20320
20321         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20322         $LFS getdirstripe $DIR/$tdir
20323
20324         files_on_starting_mdt=0
20325         for i in $(seq $total); do
20326                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20327                         error "file $tfile.$i mismatch after migration"
20328                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20329                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20330         done
20331
20332         echo "$files_on_starting_mdt files on MDT1 after migration"
20333         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20334
20335         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20336         $LFS getdirstripe $DIR/$tdir
20337
20338         files_on_starting_mdt=0
20339         for i in $(seq $total); do
20340                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20341                         error "file $tfile.$i mismatch after 2nd migration"
20342                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20343                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20344         done
20345
20346         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20347         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20348
20349         true
20350 }
20351 run_test 230k "file data not changed after dir migration"
20352
20353 test_230l() {
20354         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20355         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20356                 skip "Need MDS version at least 2.11.56"
20357
20358         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20359         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20360                 error "create files under remote dir failed $i"
20361         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20362 }
20363 run_test 230l "readdir between MDTs won't crash"
20364
20365 test_230m() {
20366         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20367         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20368                 skip "Need MDS version at least 2.11.56"
20369
20370         local MDTIDX=1
20371         local mig_dir=$DIR/$tdir/migrate_dir
20372         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20373         local shortstr="b"
20374         local val
20375
20376         echo "Creating files and dirs with xattrs"
20377         test_mkdir $DIR/$tdir
20378         test_mkdir -i0 -c1 $mig_dir
20379         mkdir $mig_dir/dir
20380         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20381                 error "cannot set xattr attr1 on dir"
20382         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20383                 error "cannot set xattr attr2 on dir"
20384         touch $mig_dir/dir/f0
20385         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20386                 error "cannot set xattr attr1 on file"
20387         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20388                 error "cannot set xattr attr2 on file"
20389         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20390         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20391         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20392         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20393         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20394         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20395         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20396         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20397         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20398
20399         echo "Migrating to MDT1"
20400         $LFS migrate -m $MDTIDX $mig_dir ||
20401                 error "fails on migrating dir to MDT1"
20402
20403         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20404         echo "Checking xattrs"
20405         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20406         [ "$val" = $longstr ] ||
20407                 error "expecting xattr1 $longstr on dir, found $val"
20408         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20409         [ "$val" = $shortstr ] ||
20410                 error "expecting xattr2 $shortstr on dir, found $val"
20411         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20412         [ "$val" = $longstr ] ||
20413                 error "expecting xattr1 $longstr on file, found $val"
20414         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20415         [ "$val" = $shortstr ] ||
20416                 error "expecting xattr2 $shortstr on file, found $val"
20417 }
20418 run_test 230m "xattrs not changed after dir migration"
20419
20420 test_230n() {
20421         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20422         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20423                 skip "Need MDS version at least 2.13.53"
20424
20425         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20426         cat /etc/hosts > $DIR/$tdir/$tfile
20427         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20428         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20429
20430         cmp /etc/hosts $DIR/$tdir/$tfile ||
20431                 error "File data mismatch after migration"
20432 }
20433 run_test 230n "Dir migration with mirrored file"
20434
20435 test_230o() {
20436         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20437         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20438                 skip "Need MDS version at least 2.13.52"
20439
20440         local mdts=$(comma_list $(mdts_nodes))
20441         local timeout=100
20442         local restripe_status
20443         local delta
20444         local i
20445
20446         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20447
20448         # in case "crush" hash type is not set
20449         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20450
20451         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20452                            mdt.*MDT0000.enable_dir_restripe)
20453         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20454         stack_trap "do_nodes $mdts $LCTL set_param \
20455                     mdt.*.enable_dir_restripe=$restripe_status"
20456
20457         mkdir $DIR/$tdir
20458         createmany -m $DIR/$tdir/f 100 ||
20459                 error "create files under remote dir failed $i"
20460         createmany -d $DIR/$tdir/d 100 ||
20461                 error "create dirs under remote dir failed $i"
20462
20463         for i in $(seq 2 $MDSCOUNT); do
20464                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20465                 $LFS setdirstripe -c $i $DIR/$tdir ||
20466                         error "split -c $i $tdir failed"
20467                 wait_update $HOSTNAME \
20468                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20469                         error "dir split not finished"
20470                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20471                         awk '/migrate/ {sum += $2} END { print sum }')
20472                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20473                 # delta is around total_files/stripe_count
20474                 (( $delta < 200 / (i - 1) + 4 )) ||
20475                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20476         done
20477 }
20478 run_test 230o "dir split"
20479
20480 test_230p() {
20481         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20482         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20483                 skip "Need MDS version at least 2.13.52"
20484
20485         local mdts=$(comma_list $(mdts_nodes))
20486         local timeout=100
20487         local restripe_status
20488         local delta
20489         local c
20490
20491         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20492
20493         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20494
20495         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20496                            mdt.*MDT0000.enable_dir_restripe)
20497         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20498         stack_trap "do_nodes $mdts $LCTL set_param \
20499                     mdt.*.enable_dir_restripe=$restripe_status"
20500
20501         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20502         createmany -m $DIR/$tdir/f 100 ||
20503                 error "create files under remote dir failed"
20504         createmany -d $DIR/$tdir/d 100 ||
20505                 error "create dirs under remote dir failed"
20506
20507         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20508                 local mdt_hash="crush"
20509
20510                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20511                 $LFS setdirstripe -c $c $DIR/$tdir ||
20512                         error "split -c $c $tdir failed"
20513                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20514                         mdt_hash="$mdt_hash,fixed"
20515                 elif [ $c -eq 1 ]; then
20516                         mdt_hash="none"
20517                 fi
20518                 wait_update $HOSTNAME \
20519                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20520                         error "dir merge not finished"
20521                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20522                         awk '/migrate/ {sum += $2} END { print sum }')
20523                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20524                 # delta is around total_files/stripe_count
20525                 (( delta < 200 / c + 4 )) ||
20526                         error "$delta files migrated >= $((200 / c + 4))"
20527         done
20528 }
20529 run_test 230p "dir merge"
20530
20531 test_230q() {
20532         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20533         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20534                 skip "Need MDS version at least 2.13.52"
20535
20536         local mdts=$(comma_list $(mdts_nodes))
20537         local saved_threshold=$(do_facet mds1 \
20538                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20539         local saved_delta=$(do_facet mds1 \
20540                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20541         local threshold=100
20542         local delta=2
20543         local total=0
20544         local stripe_count=0
20545         local stripe_index
20546         local nr_files
20547         local create
20548
20549         # test with fewer files on ZFS
20550         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20551
20552         stack_trap "do_nodes $mdts $LCTL set_param \
20553                     mdt.*.dir_split_count=$saved_threshold"
20554         stack_trap "do_nodes $mdts $LCTL set_param \
20555                     mdt.*.dir_split_delta=$saved_delta"
20556         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20557         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20558         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20559         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20560         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20561         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20562
20563         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20564         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20565
20566         create=$((threshold * 3 / 2))
20567         while [ $stripe_count -lt $MDSCOUNT ]; do
20568                 createmany -m $DIR/$tdir/f $total $create ||
20569                         error "create sub files failed"
20570                 stat $DIR/$tdir > /dev/null
20571                 total=$((total + create))
20572                 stripe_count=$((stripe_count + delta))
20573                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20574
20575                 wait_update $HOSTNAME \
20576                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20577                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20578
20579                 wait_update $HOSTNAME \
20580                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20581                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20582
20583                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20584                 echo "$nr_files/$total files on MDT$stripe_index after split"
20585                 # allow 10% margin of imbalance with crush hash
20586                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20587                         error "$nr_files files on MDT$stripe_index after split"
20588
20589                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20590                 [ $nr_files -eq $total ] ||
20591                         error "total sub files $nr_files != $total"
20592         done
20593
20594         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20595
20596         echo "fixed layout directory won't auto split"
20597         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20598         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20599                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20600         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20601                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20602 }
20603 run_test 230q "dir auto split"
20604
20605 test_230r() {
20606         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20607         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20608         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20609                 skip "Need MDS version at least 2.13.54"
20610
20611         # maximum amount of local locks:
20612         # parent striped dir - 2 locks
20613         # new stripe in parent to migrate to - 1 lock
20614         # source and target - 2 locks
20615         # Total 5 locks for regular file
20616         mkdir -p $DIR/$tdir
20617         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20618         touch $DIR/$tdir/dir1/eee
20619
20620         # create 4 hardlink for 4 more locks
20621         # Total: 9 locks > RS_MAX_LOCKS (8)
20622         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20623         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20624         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20625         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20626         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20627         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20628         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20629         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20630
20631         cancel_lru_locks mdc
20632
20633         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20634                 error "migrate dir fails"
20635
20636         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20637 }
20638 run_test 230r "migrate with too many local locks"
20639
20640 test_230s() {
20641         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20642                 skip "Need MDS version at least 2.14.52"
20643
20644         local mdts=$(comma_list $(mdts_nodes))
20645         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20646                                 mdt.*MDT0000.enable_dir_restripe)
20647
20648         stack_trap "do_nodes $mdts $LCTL set_param \
20649                     mdt.*.enable_dir_restripe=$restripe_status"
20650
20651         local st
20652         for st in 0 1; do
20653                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20654                 test_mkdir $DIR/$tdir
20655                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20656                         error "$LFS mkdir should return EEXIST if target exists"
20657                 rmdir $DIR/$tdir
20658         done
20659 }
20660 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20661
20662 test_230t()
20663 {
20664         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20665         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20666                 skip "Need MDS version at least 2.14.50"
20667
20668         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20669         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20670         $LFS project -p 1 -s $DIR/$tdir ||
20671                 error "set $tdir project id failed"
20672         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20673                 error "set subdir project id failed"
20674         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20675 }
20676 run_test 230t "migrate directory with project ID set"
20677
20678 test_230u()
20679 {
20680         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20681         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20682                 skip "Need MDS version at least 2.14.53"
20683
20684         local count
20685
20686         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20687         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20688         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20689         for i in $(seq 0 $((MDSCOUNT - 1))); do
20690                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20691                 echo "$count dirs migrated to MDT$i"
20692         done
20693         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20694         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20695 }
20696 run_test 230u "migrate directory by QOS"
20697
20698 test_230v()
20699 {
20700         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20701         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20702                 skip "Need MDS version at least 2.14.53"
20703
20704         local count
20705
20706         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20707         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20708         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20709         for i in $(seq 0 $((MDSCOUNT - 1))); do
20710                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20711                 echo "$count subdirs migrated to MDT$i"
20712                 (( i == 3 )) && (( count > 0 )) &&
20713                         error "subdir shouldn't be migrated to MDT3"
20714         done
20715         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20716         (( count == 3 )) || error "dirs migrated to $count MDTs"
20717 }
20718 run_test 230v "subdir migrated to the MDT where its parent is located"
20719
20720 test_230w() {
20721         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20722         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20723                 skip "Need MDS version at least 2.15.0"
20724
20725         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20726         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20727         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20728
20729         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20730                 error "migrate failed"
20731
20732         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20733                 error "$tdir stripe count mismatch"
20734
20735         for i in $(seq 0 9); do
20736                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20737                         error "d$i is striped"
20738         done
20739 }
20740 run_test 230w "non-recursive mode dir migration"
20741
20742 test_231a()
20743 {
20744         # For simplicity this test assumes that max_pages_per_rpc
20745         # is the same across all OSCs
20746         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20747         local bulk_size=$((max_pages * PAGE_SIZE))
20748         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20749                                        head -n 1)
20750
20751         mkdir -p $DIR/$tdir
20752         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20753                 error "failed to set stripe with -S ${brw_size}M option"
20754
20755         # clear the OSC stats
20756         $LCTL set_param osc.*.stats=0 &>/dev/null
20757         stop_writeback
20758
20759         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20760         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20761                 oflag=direct &>/dev/null || error "dd failed"
20762
20763         sync; sleep 1; sync # just to be safe
20764         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20765         if [ x$nrpcs != "x1" ]; then
20766                 $LCTL get_param osc.*.stats
20767                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20768         fi
20769
20770         start_writeback
20771         # Drop the OSC cache, otherwise we will read from it
20772         cancel_lru_locks osc
20773
20774         # clear the OSC stats
20775         $LCTL set_param osc.*.stats=0 &>/dev/null
20776
20777         # Client reads $bulk_size.
20778         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20779                 iflag=direct &>/dev/null || error "dd failed"
20780
20781         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20782         if [ x$nrpcs != "x1" ]; then
20783                 $LCTL get_param osc.*.stats
20784                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20785         fi
20786 }
20787 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20788
20789 test_231b() {
20790         mkdir -p $DIR/$tdir
20791         local i
20792         for i in {0..1023}; do
20793                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20794                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20795                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20796         done
20797         sync
20798 }
20799 run_test 231b "must not assert on fully utilized OST request buffer"
20800
20801 test_232a() {
20802         mkdir -p $DIR/$tdir
20803         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20804
20805         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20806         do_facet ost1 $LCTL set_param fail_loc=0x31c
20807
20808         # ignore dd failure
20809         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20810
20811         do_facet ost1 $LCTL set_param fail_loc=0
20812         umount_client $MOUNT || error "umount failed"
20813         mount_client $MOUNT || error "mount failed"
20814         stop ost1 || error "cannot stop ost1"
20815         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20816 }
20817 run_test 232a "failed lock should not block umount"
20818
20819 test_232b() {
20820         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20821                 skip "Need MDS version at least 2.10.58"
20822
20823         mkdir -p $DIR/$tdir
20824         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20825         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20826         sync
20827         cancel_lru_locks osc
20828
20829         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20830         do_facet ost1 $LCTL set_param fail_loc=0x31c
20831
20832         # ignore failure
20833         $LFS data_version $DIR/$tdir/$tfile || true
20834
20835         do_facet ost1 $LCTL set_param fail_loc=0
20836         umount_client $MOUNT || error "umount failed"
20837         mount_client $MOUNT || error "mount failed"
20838         stop ost1 || error "cannot stop ost1"
20839         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20840 }
20841 run_test 232b "failed data version lock should not block umount"
20842
20843 test_233a() {
20844         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20845                 skip "Need MDS version at least 2.3.64"
20846         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20847
20848         local fid=$($LFS path2fid $MOUNT)
20849
20850         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20851                 error "cannot access $MOUNT using its FID '$fid'"
20852 }
20853 run_test 233a "checking that OBF of the FS root succeeds"
20854
20855 test_233b() {
20856         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20857                 skip "Need MDS version at least 2.5.90"
20858         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20859
20860         local fid=$($LFS path2fid $MOUNT/.lustre)
20861
20862         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20863                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20864
20865         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20866         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20867                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20868 }
20869 run_test 233b "checking that OBF of the FS .lustre succeeds"
20870
20871 test_234() {
20872         local p="$TMP/sanityN-$TESTNAME.parameters"
20873         save_lustre_params client "llite.*.xattr_cache" > $p
20874         lctl set_param llite.*.xattr_cache 1 ||
20875                 skip_env "xattr cache is not supported"
20876
20877         mkdir -p $DIR/$tdir || error "mkdir failed"
20878         touch $DIR/$tdir/$tfile || error "touch failed"
20879         # OBD_FAIL_LLITE_XATTR_ENOMEM
20880         $LCTL set_param fail_loc=0x1405
20881         getfattr -n user.attr $DIR/$tdir/$tfile &&
20882                 error "getfattr should have failed with ENOMEM"
20883         $LCTL set_param fail_loc=0x0
20884         rm -rf $DIR/$tdir
20885
20886         restore_lustre_params < $p
20887         rm -f $p
20888 }
20889 run_test 234 "xattr cache should not crash on ENOMEM"
20890
20891 test_235() {
20892         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20893                 skip "Need MDS version at least 2.4.52"
20894
20895         flock_deadlock $DIR/$tfile
20896         local RC=$?
20897         case $RC in
20898                 0)
20899                 ;;
20900                 124) error "process hangs on a deadlock"
20901                 ;;
20902                 *) error "error executing flock_deadlock $DIR/$tfile"
20903                 ;;
20904         esac
20905 }
20906 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20907
20908 #LU-2935
20909 test_236() {
20910         check_swap_layouts_support
20911
20912         local ref1=/etc/passwd
20913         local ref2=/etc/group
20914         local file1=$DIR/$tdir/f1
20915         local file2=$DIR/$tdir/f2
20916
20917         test_mkdir -c1 $DIR/$tdir
20918         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20919         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20920         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20921         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20922         local fd=$(free_fd)
20923         local cmd="exec $fd<>$file2"
20924         eval $cmd
20925         rm $file2
20926         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20927                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20928         cmd="exec $fd>&-"
20929         eval $cmd
20930         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20931
20932         #cleanup
20933         rm -rf $DIR/$tdir
20934 }
20935 run_test 236 "Layout swap on open unlinked file"
20936
20937 # LU-4659 linkea consistency
20938 test_238() {
20939         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20940                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20941                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20942                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20943
20944         touch $DIR/$tfile
20945         ln $DIR/$tfile $DIR/$tfile.lnk
20946         touch $DIR/$tfile.new
20947         mv $DIR/$tfile.new $DIR/$tfile
20948         local fid1=$($LFS path2fid $DIR/$tfile)
20949         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20950         local path1=$($LFS fid2path $FSNAME "$fid1")
20951         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20952         local path2=$($LFS fid2path $FSNAME "$fid2")
20953         [ $tfile.lnk == $path2 ] ||
20954                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20955         rm -f $DIR/$tfile*
20956 }
20957 run_test 238 "Verify linkea consistency"
20958
20959 test_239A() { # was test_239
20960         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20961                 skip "Need MDS version at least 2.5.60"
20962
20963         local list=$(comma_list $(mdts_nodes))
20964
20965         mkdir -p $DIR/$tdir
20966         createmany -o $DIR/$tdir/f- 5000
20967         unlinkmany $DIR/$tdir/f- 5000
20968         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20969                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20970         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20971                         osp.*MDT*.sync_in_flight" | calc_sum)
20972         [ "$changes" -eq 0 ] || error "$changes not synced"
20973 }
20974 run_test 239A "osp_sync test"
20975
20976 test_239a() { #LU-5297
20977         remote_mds_nodsh && skip "remote MDS with nodsh"
20978
20979         touch $DIR/$tfile
20980         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20981         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20982         chgrp $RUNAS_GID $DIR/$tfile
20983         wait_delete_completed
20984 }
20985 run_test 239a "process invalid osp sync record correctly"
20986
20987 test_239b() { #LU-5297
20988         remote_mds_nodsh && skip "remote MDS with nodsh"
20989
20990         touch $DIR/$tfile1
20991         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20992         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20993         chgrp $RUNAS_GID $DIR/$tfile1
20994         wait_delete_completed
20995         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20996         touch $DIR/$tfile2
20997         chgrp $RUNAS_GID $DIR/$tfile2
20998         wait_delete_completed
20999 }
21000 run_test 239b "process osp sync record with ENOMEM error correctly"
21001
21002 test_240() {
21003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21004         remote_mds_nodsh && skip "remote MDS with nodsh"
21005
21006         mkdir -p $DIR/$tdir
21007
21008         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21009                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21010         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21011                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21012
21013         umount_client $MOUNT || error "umount failed"
21014         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21015         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21016         mount_client $MOUNT || error "failed to mount client"
21017
21018         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21019         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21020 }
21021 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21022
21023 test_241_bio() {
21024         local count=$1
21025         local bsize=$2
21026
21027         for LOOP in $(seq $count); do
21028                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21029                 cancel_lru_locks $OSC || true
21030         done
21031 }
21032
21033 test_241_dio() {
21034         local count=$1
21035         local bsize=$2
21036
21037         for LOOP in $(seq $1); do
21038                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21039                         2>/dev/null
21040         done
21041 }
21042
21043 test_241a() { # was test_241
21044         local bsize=$PAGE_SIZE
21045
21046         (( bsize < 40960 )) && bsize=40960
21047         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21048         ls -la $DIR/$tfile
21049         cancel_lru_locks $OSC
21050         test_241_bio 1000 $bsize &
21051         PID=$!
21052         test_241_dio 1000 $bsize
21053         wait $PID
21054 }
21055 run_test 241a "bio vs dio"
21056
21057 test_241b() {
21058         local bsize=$PAGE_SIZE
21059
21060         (( bsize < 40960 )) && bsize=40960
21061         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21062         ls -la $DIR/$tfile
21063         test_241_dio 1000 $bsize &
21064         PID=$!
21065         test_241_dio 1000 $bsize
21066         wait $PID
21067 }
21068 run_test 241b "dio vs dio"
21069
21070 test_242() {
21071         remote_mds_nodsh && skip "remote MDS with nodsh"
21072
21073         mkdir_on_mdt0 $DIR/$tdir
21074         touch $DIR/$tdir/$tfile
21075
21076         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21077         do_facet mds1 lctl set_param fail_loc=0x105
21078         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21079
21080         do_facet mds1 lctl set_param fail_loc=0
21081         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21082 }
21083 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21084
21085 test_243()
21086 {
21087         test_mkdir $DIR/$tdir
21088         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21089 }
21090 run_test 243 "various group lock tests"
21091
21092 test_244a()
21093 {
21094         test_mkdir $DIR/$tdir
21095         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21096         sendfile_grouplock $DIR/$tdir/$tfile || \
21097                 error "sendfile+grouplock failed"
21098         rm -rf $DIR/$tdir
21099 }
21100 run_test 244a "sendfile with group lock tests"
21101
21102 test_244b()
21103 {
21104         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21105
21106         local threads=50
21107         local size=$((1024*1024))
21108
21109         test_mkdir $DIR/$tdir
21110         for i in $(seq 1 $threads); do
21111                 local file=$DIR/$tdir/file_$((i / 10))
21112                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21113                 local pids[$i]=$!
21114         done
21115         for i in $(seq 1 $threads); do
21116                 wait ${pids[$i]}
21117         done
21118 }
21119 run_test 244b "multi-threaded write with group lock"
21120
21121 test_245a() {
21122         local flagname="multi_mod_rpcs"
21123         local connect_data_name="max_mod_rpcs"
21124         local out
21125
21126         # check if multiple modify RPCs flag is set
21127         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21128                 grep "connect_flags:")
21129         echo "$out"
21130
21131         echo "$out" | grep -qw $flagname
21132         if [ $? -ne 0 ]; then
21133                 echo "connect flag $flagname is not set"
21134                 return
21135         fi
21136
21137         # check if multiple modify RPCs data is set
21138         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21139         echo "$out"
21140
21141         echo "$out" | grep -qw $connect_data_name ||
21142                 error "import should have connect data $connect_data_name"
21143 }
21144 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21145
21146 test_245b() {
21147         local flagname="multi_mod_rpcs"
21148         local connect_data_name="max_mod_rpcs"
21149         local out
21150
21151         remote_mds_nodsh && skip "remote MDS with nodsh"
21152         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21153
21154         # check if multiple modify RPCs flag is set
21155         out=$(do_facet mds1 \
21156               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21157               grep "connect_flags:")
21158         echo "$out"
21159
21160         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21161
21162         # check if multiple modify RPCs data is set
21163         out=$(do_facet mds1 \
21164               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21165
21166         [[ "$out" =~ $connect_data_name ]] ||
21167                 {
21168                         echo "$out"
21169                         error "missing connect data $connect_data_name"
21170                 }
21171 }
21172 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21173
21174 cleanup_247() {
21175         local submount=$1
21176
21177         trap 0
21178         umount_client $submount
21179         rmdir $submount
21180 }
21181
21182 test_247a() {
21183         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21184                 grep -q subtree ||
21185                 skip_env "Fileset feature is not supported"
21186
21187         local submount=${MOUNT}_$tdir
21188
21189         mkdir $MOUNT/$tdir
21190         mkdir -p $submount || error "mkdir $submount failed"
21191         FILESET="$FILESET/$tdir" mount_client $submount ||
21192                 error "mount $submount failed"
21193         trap "cleanup_247 $submount" EXIT
21194         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21195         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21196                 error "read $MOUNT/$tdir/$tfile failed"
21197         cleanup_247 $submount
21198 }
21199 run_test 247a "mount subdir as fileset"
21200
21201 test_247b() {
21202         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21203                 skip_env "Fileset feature is not supported"
21204
21205         local submount=${MOUNT}_$tdir
21206
21207         rm -rf $MOUNT/$tdir
21208         mkdir -p $submount || error "mkdir $submount failed"
21209         SKIP_FILESET=1
21210         FILESET="$FILESET/$tdir" mount_client $submount &&
21211                 error "mount $submount should fail"
21212         rmdir $submount
21213 }
21214 run_test 247b "mount subdir that dose not exist"
21215
21216 test_247c() {
21217         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21218                 skip_env "Fileset feature is not supported"
21219
21220         local submount=${MOUNT}_$tdir
21221
21222         mkdir -p $MOUNT/$tdir/dir1
21223         mkdir -p $submount || error "mkdir $submount failed"
21224         trap "cleanup_247 $submount" EXIT
21225         FILESET="$FILESET/$tdir" mount_client $submount ||
21226                 error "mount $submount failed"
21227         local fid=$($LFS path2fid $MOUNT/)
21228         $LFS fid2path $submount $fid && error "fid2path should fail"
21229         cleanup_247 $submount
21230 }
21231 run_test 247c "running fid2path outside subdirectory root"
21232
21233 test_247d() {
21234         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21235                 skip "Fileset feature is not supported"
21236
21237         local submount=${MOUNT}_$tdir
21238
21239         mkdir -p $MOUNT/$tdir/dir1
21240         mkdir -p $submount || error "mkdir $submount failed"
21241         FILESET="$FILESET/$tdir" mount_client $submount ||
21242                 error "mount $submount failed"
21243         trap "cleanup_247 $submount" EXIT
21244
21245         local td=$submount/dir1
21246         local fid=$($LFS path2fid $td)
21247         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21248
21249         # check that we get the same pathname back
21250         local rootpath
21251         local found
21252         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21253                 echo "$rootpath $fid"
21254                 found=$($LFS fid2path $rootpath "$fid")
21255                 [ -n "$found" ] || error "fid2path should succeed"
21256                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21257         done
21258         # check wrong root path format
21259         rootpath=$submount"_wrong"
21260         found=$($LFS fid2path $rootpath "$fid")
21261         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21262
21263         cleanup_247 $submount
21264 }
21265 run_test 247d "running fid2path inside subdirectory root"
21266
21267 # LU-8037
21268 test_247e() {
21269         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21270                 grep -q subtree ||
21271                 skip "Fileset feature is not supported"
21272
21273         local submount=${MOUNT}_$tdir
21274
21275         mkdir $MOUNT/$tdir
21276         mkdir -p $submount || error "mkdir $submount failed"
21277         FILESET="$FILESET/.." mount_client $submount &&
21278                 error "mount $submount should fail"
21279         rmdir $submount
21280 }
21281 run_test 247e "mount .. as fileset"
21282
21283 test_247f() {
21284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21285         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21286                 skip "Need at least version 2.13.52"
21287         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21288                 skip "Need at least version 2.14.50"
21289         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21290                 grep -q subtree ||
21291                 skip "Fileset feature is not supported"
21292
21293         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21294         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21295                 error "mkdir remote failed"
21296         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21297                 error "mkdir remote/subdir failed"
21298         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21299                 error "mkdir striped failed"
21300         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21301
21302         local submount=${MOUNT}_$tdir
21303
21304         mkdir -p $submount || error "mkdir $submount failed"
21305         stack_trap "rmdir $submount"
21306
21307         local dir
21308         local stat
21309         local fileset=$FILESET
21310         local mdts=$(comma_list $(mdts_nodes))
21311
21312         stat=$(do_facet mds1 $LCTL get_param -n \
21313                 mdt.*MDT0000.enable_remote_subdir_mount)
21314         stack_trap "do_nodes $mdts $LCTL set_param \
21315                 mdt.*.enable_remote_subdir_mount=$stat"
21316
21317         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21318         stack_trap "umount_client $submount"
21319         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21320                 error "mount remote dir $dir should fail"
21321
21322         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21323                 $tdir/striped/. ; do
21324                 FILESET="$fileset/$dir" mount_client $submount ||
21325                         error "mount $dir failed"
21326                 umount_client $submount
21327         done
21328
21329         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21330         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21331                 error "mount $tdir/remote failed"
21332 }
21333 run_test 247f "mount striped or remote directory as fileset"
21334
21335 test_247g() {
21336         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21337         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21338                 skip "Need at least version 2.14.50"
21339
21340         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21341                 error "mkdir $tdir failed"
21342         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21343
21344         local submount=${MOUNT}_$tdir
21345
21346         mkdir -p $submount || error "mkdir $submount failed"
21347         stack_trap "rmdir $submount"
21348
21349         FILESET="$fileset/$tdir" mount_client $submount ||
21350                 error "mount $dir failed"
21351         stack_trap "umount $submount"
21352
21353         local mdts=$(comma_list $(mdts_nodes))
21354
21355         local nrpcs
21356
21357         stat $submount > /dev/null
21358         cancel_lru_locks $MDC
21359         stat $submount > /dev/null
21360         stat $submount/$tfile > /dev/null
21361         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21362         stat $submount/$tfile > /dev/null
21363         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21364                 awk '/getattr/ {sum += $2} END {print sum}')
21365
21366         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21367 }
21368 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21369
21370 test_248a() {
21371         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21372         [ -z "$fast_read_sav" ] && skip "no fast read support"
21373
21374         # create a large file for fast read verification
21375         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21376
21377         # make sure the file is created correctly
21378         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21379                 { rm -f $DIR/$tfile; skip "file creation error"; }
21380
21381         echo "Test 1: verify that fast read is 4 times faster on cache read"
21382
21383         # small read with fast read enabled
21384         $LCTL set_param -n llite.*.fast_read=1
21385         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21386                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21387                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21388         # small read with fast read disabled
21389         $LCTL set_param -n llite.*.fast_read=0
21390         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21391                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21392                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21393
21394         # verify that fast read is 4 times faster for cache read
21395         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21396                 error_not_in_vm "fast read was not 4 times faster: " \
21397                            "$t_fast vs $t_slow"
21398
21399         echo "Test 2: verify the performance between big and small read"
21400         $LCTL set_param -n llite.*.fast_read=1
21401
21402         # 1k non-cache read
21403         cancel_lru_locks osc
21404         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21405                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21406                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21407
21408         # 1M non-cache read
21409         cancel_lru_locks osc
21410         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21411                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21412                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21413
21414         # verify that big IO is not 4 times faster than small IO
21415         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21416                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21417
21418         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21419         rm -f $DIR/$tfile
21420 }
21421 run_test 248a "fast read verification"
21422
21423 test_248b() {
21424         # Default short_io_bytes=16384, try both smaller and larger sizes.
21425         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21426         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21427         echo "bs=53248 count=113 normal buffered write"
21428         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21429                 error "dd of initial data file failed"
21430         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21431
21432         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21433         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21434                 error "dd with sync normal writes failed"
21435         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21436
21437         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21438         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21439                 error "dd with sync small writes failed"
21440         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21441
21442         cancel_lru_locks osc
21443
21444         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21445         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21446         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21447         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21448                 iflag=direct || error "dd with O_DIRECT small read failed"
21449         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21450         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21451                 error "compare $TMP/$tfile.1 failed"
21452
21453         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21454         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21455
21456         # just to see what the maximum tunable value is, and test parsing
21457         echo "test invalid parameter 2MB"
21458         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21459                 error "too-large short_io_bytes allowed"
21460         echo "test maximum parameter 512KB"
21461         # if we can set a larger short_io_bytes, run test regardless of version
21462         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21463                 # older clients may not allow setting it this large, that's OK
21464                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21465                         skip "Need at least client version 2.13.50"
21466                 error "medium short_io_bytes failed"
21467         fi
21468         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21469         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21470
21471         echo "test large parameter 64KB"
21472         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21473         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21474
21475         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21476         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21477                 error "dd with sync large writes failed"
21478         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21479
21480         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21481         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21482         num=$((113 * 4096 / PAGE_SIZE))
21483         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21484         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21485                 error "dd with O_DIRECT large writes failed"
21486         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21487                 error "compare $DIR/$tfile.3 failed"
21488
21489         cancel_lru_locks osc
21490
21491         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21492         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21493                 error "dd with O_DIRECT large read failed"
21494         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21495                 error "compare $TMP/$tfile.2 failed"
21496
21497         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21498         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21499                 error "dd with O_DIRECT large read failed"
21500         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21501                 error "compare $TMP/$tfile.3 failed"
21502 }
21503 run_test 248b "test short_io read and write for both small and large sizes"
21504
21505 test_249() { # LU-7890
21506         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21507                 skip "Need at least version 2.8.54"
21508
21509         rm -f $DIR/$tfile
21510         $LFS setstripe -c 1 $DIR/$tfile
21511         # Offset 2T == 4k * 512M
21512         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21513                 error "dd to 2T offset failed"
21514 }
21515 run_test 249 "Write above 2T file size"
21516
21517 test_250() {
21518         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21519          && skip "no 16TB file size limit on ZFS"
21520
21521         $LFS setstripe -c 1 $DIR/$tfile
21522         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21523         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21524         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21525         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21526                 conv=notrunc,fsync && error "append succeeded"
21527         return 0
21528 }
21529 run_test 250 "Write above 16T limit"
21530
21531 test_251() {
21532         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21533
21534         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21535         #Skip once - writing the first stripe will succeed
21536         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21537         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21538                 error "short write happened"
21539
21540         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21541         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21542                 error "short read happened"
21543
21544         rm -f $DIR/$tfile
21545 }
21546 run_test 251 "Handling short read and write correctly"
21547
21548 test_252() {
21549         remote_mds_nodsh && skip "remote MDS with nodsh"
21550         remote_ost_nodsh && skip "remote OST with nodsh"
21551         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21552                 skip_env "ldiskfs only test"
21553         fi
21554
21555         local tgt
21556         local dev
21557         local out
21558         local uuid
21559         local num
21560         local gen
21561
21562         # check lr_reader on OST0000
21563         tgt=ost1
21564         dev=$(facet_device $tgt)
21565         out=$(do_facet $tgt $LR_READER $dev)
21566         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21567         echo "$out"
21568         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21569         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21570                 error "Invalid uuid returned by $LR_READER on target $tgt"
21571         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21572
21573         # check lr_reader -c on MDT0000
21574         tgt=mds1
21575         dev=$(facet_device $tgt)
21576         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21577                 skip "$LR_READER does not support additional options"
21578         fi
21579         out=$(do_facet $tgt $LR_READER -c $dev)
21580         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21581         echo "$out"
21582         num=$(echo "$out" | grep -c "mdtlov")
21583         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21584                 error "Invalid number of mdtlov clients returned by $LR_READER"
21585         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21586
21587         # check lr_reader -cr on MDT0000
21588         out=$(do_facet $tgt $LR_READER -cr $dev)
21589         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21590         echo "$out"
21591         echo "$out" | grep -q "^reply_data:$" ||
21592                 error "$LR_READER should have returned 'reply_data' section"
21593         num=$(echo "$out" | grep -c "client_generation")
21594         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21595 }
21596 run_test 252 "check lr_reader tool"
21597
21598 test_253() {
21599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21600         remote_mds_nodsh && skip "remote MDS with nodsh"
21601         remote_mgs_nodsh && skip "remote MGS with nodsh"
21602
21603         local ostidx=0
21604         local rc=0
21605         local ost_name=$(ostname_from_index $ostidx)
21606
21607         # on the mdt's osc
21608         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21609         do_facet $SINGLEMDS $LCTL get_param -n \
21610                 osp.$mdtosc_proc1.reserved_mb_high ||
21611                 skip  "remote MDS does not support reserved_mb_high"
21612
21613         rm -rf $DIR/$tdir
21614         wait_mds_ost_sync
21615         wait_delete_completed
21616         mkdir $DIR/$tdir
21617
21618         pool_add $TESTNAME || error "Pool creation failed"
21619         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21620
21621         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21622                 error "Setstripe failed"
21623
21624         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21625
21626         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21627                     grep "watermarks")
21628         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21629
21630         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21631                         osp.$mdtosc_proc1.prealloc_status)
21632         echo "prealloc_status $oa_status"
21633
21634         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21635                 error "File creation should fail"
21636
21637         #object allocation was stopped, but we still able to append files
21638         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21639                 oflag=append || error "Append failed"
21640
21641         rm -f $DIR/$tdir/$tfile.0
21642
21643         # For this test, we want to delete the files we created to go out of
21644         # space but leave the watermark, so we remain nearly out of space
21645         ost_watermarks_enospc_delete_files $tfile $ostidx
21646
21647         wait_delete_completed
21648
21649         sleep_maxage
21650
21651         for i in $(seq 10 12); do
21652                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21653                         2>/dev/null || error "File creation failed after rm"
21654         done
21655
21656         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21657                         osp.$mdtosc_proc1.prealloc_status)
21658         echo "prealloc_status $oa_status"
21659
21660         if (( oa_status != 0 )); then
21661                 error "Object allocation still disable after rm"
21662         fi
21663 }
21664 run_test 253 "Check object allocation limit"
21665
21666 test_254() {
21667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21668         remote_mds_nodsh && skip "remote MDS with nodsh"
21669
21670         local mdt=$(facet_svc $SINGLEMDS)
21671
21672         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21673                 skip "MDS does not support changelog_size"
21674
21675         local cl_user
21676
21677         changelog_register || error "changelog_register failed"
21678
21679         changelog_clear 0 || error "changelog_clear failed"
21680
21681         local size1=$(do_facet $SINGLEMDS \
21682                       $LCTL get_param -n mdd.$mdt.changelog_size)
21683         echo "Changelog size $size1"
21684
21685         rm -rf $DIR/$tdir
21686         $LFS mkdir -i 0 $DIR/$tdir
21687         # change something
21688         mkdir -p $DIR/$tdir/pics/2008/zachy
21689         touch $DIR/$tdir/pics/2008/zachy/timestamp
21690         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21691         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21692         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21693         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21694         rm $DIR/$tdir/pics/desktop.jpg
21695
21696         local size2=$(do_facet $SINGLEMDS \
21697                       $LCTL get_param -n mdd.$mdt.changelog_size)
21698         echo "Changelog size after work $size2"
21699
21700         (( $size2 > $size1 )) ||
21701                 error "new Changelog size=$size2 less than old size=$size1"
21702 }
21703 run_test 254 "Check changelog size"
21704
21705 ladvise_no_type()
21706 {
21707         local type=$1
21708         local file=$2
21709
21710         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21711                 awk -F: '{print $2}' | grep $type > /dev/null
21712         if [ $? -ne 0 ]; then
21713                 return 0
21714         fi
21715         return 1
21716 }
21717
21718 ladvise_no_ioctl()
21719 {
21720         local file=$1
21721
21722         lfs ladvise -a willread $file > /dev/null 2>&1
21723         if [ $? -eq 0 ]; then
21724                 return 1
21725         fi
21726
21727         lfs ladvise -a willread $file 2>&1 |
21728                 grep "Inappropriate ioctl for device" > /dev/null
21729         if [ $? -eq 0 ]; then
21730                 return 0
21731         fi
21732         return 1
21733 }
21734
21735 percent() {
21736         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21737 }
21738
21739 # run a random read IO workload
21740 # usage: random_read_iops <filename> <filesize> <iosize>
21741 random_read_iops() {
21742         local file=$1
21743         local fsize=$2
21744         local iosize=${3:-4096}
21745
21746         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21747                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21748 }
21749
21750 drop_file_oss_cache() {
21751         local file="$1"
21752         local nodes="$2"
21753
21754         $LFS ladvise -a dontneed $file 2>/dev/null ||
21755                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21756 }
21757
21758 ladvise_willread_performance()
21759 {
21760         local repeat=10
21761         local average_origin=0
21762         local average_cache=0
21763         local average_ladvise=0
21764
21765         for ((i = 1; i <= $repeat; i++)); do
21766                 echo "Iter $i/$repeat: reading without willread hint"
21767                 cancel_lru_locks osc
21768                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21769                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21770                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21771                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21772
21773                 cancel_lru_locks osc
21774                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21775                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21776                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21777
21778                 cancel_lru_locks osc
21779                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21780                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21781                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21782                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21783                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21784         done
21785         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21786         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21787         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21788
21789         speedup_cache=$(percent $average_cache $average_origin)
21790         speedup_ladvise=$(percent $average_ladvise $average_origin)
21791
21792         echo "Average uncached read: $average_origin"
21793         echo "Average speedup with OSS cached read: " \
21794                 "$average_cache = +$speedup_cache%"
21795         echo "Average speedup with ladvise willread: " \
21796                 "$average_ladvise = +$speedup_ladvise%"
21797
21798         local lowest_speedup=20
21799         if (( ${average_cache%.*} < $lowest_speedup )); then
21800                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21801                      " got $average_cache%. Skipping ladvise willread check."
21802                 return 0
21803         fi
21804
21805         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21806         # it is still good to run until then to exercise 'ladvise willread'
21807         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21808                 [ "$ost1_FSTYPE" = "zfs" ] &&
21809                 echo "osd-zfs does not support dontneed or drop_caches" &&
21810                 return 0
21811
21812         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21813         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21814                 error_not_in_vm "Speedup with willread is less than " \
21815                         "$lowest_speedup%, got $average_ladvise%"
21816 }
21817
21818 test_255a() {
21819         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21820                 skip "lustre < 2.8.54 does not support ladvise "
21821         remote_ost_nodsh && skip "remote OST with nodsh"
21822
21823         stack_trap "rm -f $DIR/$tfile"
21824         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21825
21826         ladvise_no_type willread $DIR/$tfile &&
21827                 skip "willread ladvise is not supported"
21828
21829         ladvise_no_ioctl $DIR/$tfile &&
21830                 skip "ladvise ioctl is not supported"
21831
21832         local size_mb=100
21833         local size=$((size_mb * 1048576))
21834         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21835                 error "dd to $DIR/$tfile failed"
21836
21837         lfs ladvise -a willread $DIR/$tfile ||
21838                 error "Ladvise failed with no range argument"
21839
21840         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21841                 error "Ladvise failed with no -l or -e argument"
21842
21843         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21844                 error "Ladvise failed with only -e argument"
21845
21846         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21847                 error "Ladvise failed with only -l argument"
21848
21849         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21850                 error "End offset should not be smaller than start offset"
21851
21852         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21853                 error "End offset should not be equal to start offset"
21854
21855         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21856                 error "Ladvise failed with overflowing -s argument"
21857
21858         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21859                 error "Ladvise failed with overflowing -e argument"
21860
21861         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21862                 error "Ladvise failed with overflowing -l argument"
21863
21864         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21865                 error "Ladvise succeeded with conflicting -l and -e arguments"
21866
21867         echo "Synchronous ladvise should wait"
21868         local delay=4
21869 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21870         do_nodes $(comma_list $(osts_nodes)) \
21871                 $LCTL set_param fail_val=$delay fail_loc=0x237
21872
21873         local start_ts=$SECONDS
21874         lfs ladvise -a willread $DIR/$tfile ||
21875                 error "Ladvise failed with no range argument"
21876         local end_ts=$SECONDS
21877         local inteval_ts=$((end_ts - start_ts))
21878
21879         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21880                 error "Synchronous advice didn't wait reply"
21881         fi
21882
21883         echo "Asynchronous ladvise shouldn't wait"
21884         local start_ts=$SECONDS
21885         lfs ladvise -a willread -b $DIR/$tfile ||
21886                 error "Ladvise failed with no range argument"
21887         local end_ts=$SECONDS
21888         local inteval_ts=$((end_ts - start_ts))
21889
21890         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21891                 error "Asynchronous advice blocked"
21892         fi
21893
21894         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21895         ladvise_willread_performance
21896 }
21897 run_test 255a "check 'lfs ladvise -a willread'"
21898
21899 facet_meminfo() {
21900         local facet=$1
21901         local info=$2
21902
21903         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21904 }
21905
21906 test_255b() {
21907         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21908                 skip "lustre < 2.8.54 does not support ladvise "
21909         remote_ost_nodsh && skip "remote OST with nodsh"
21910
21911         stack_trap "rm -f $DIR/$tfile"
21912         lfs setstripe -c 1 -i 0 $DIR/$tfile
21913
21914         ladvise_no_type dontneed $DIR/$tfile &&
21915                 skip "dontneed ladvise is not supported"
21916
21917         ladvise_no_ioctl $DIR/$tfile &&
21918                 skip "ladvise ioctl is not supported"
21919
21920         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21921                 [ "$ost1_FSTYPE" = "zfs" ] &&
21922                 skip "zfs-osd does not support 'ladvise dontneed'"
21923
21924         local size_mb=100
21925         local size=$((size_mb * 1048576))
21926         # In order to prevent disturbance of other processes, only check 3/4
21927         # of the memory usage
21928         local kibibytes=$((size_mb * 1024 * 3 / 4))
21929
21930         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21931                 error "dd to $DIR/$tfile failed"
21932
21933         #force write to complete before dropping OST cache & checking memory
21934         sync
21935
21936         local total=$(facet_meminfo ost1 MemTotal)
21937         echo "Total memory: $total KiB"
21938
21939         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21940         local before_read=$(facet_meminfo ost1 Cached)
21941         echo "Cache used before read: $before_read KiB"
21942
21943         lfs ladvise -a willread $DIR/$tfile ||
21944                 error "Ladvise willread failed"
21945         local after_read=$(facet_meminfo ost1 Cached)
21946         echo "Cache used after read: $after_read KiB"
21947
21948         lfs ladvise -a dontneed $DIR/$tfile ||
21949                 error "Ladvise dontneed again failed"
21950         local no_read=$(facet_meminfo ost1 Cached)
21951         echo "Cache used after dontneed ladvise: $no_read KiB"
21952
21953         if [ $total -lt $((before_read + kibibytes)) ]; then
21954                 echo "Memory is too small, abort checking"
21955                 return 0
21956         fi
21957
21958         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21959                 error "Ladvise willread should use more memory" \
21960                         "than $kibibytes KiB"
21961         fi
21962
21963         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21964                 error "Ladvise dontneed should release more memory" \
21965                         "than $kibibytes KiB"
21966         fi
21967 }
21968 run_test 255b "check 'lfs ladvise -a dontneed'"
21969
21970 test_255c() {
21971         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21972                 skip "lustre < 2.10.50 does not support lockahead"
21973
21974         local ost1_imp=$(get_osc_import_name client ost1)
21975         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21976                          cut -d'.' -f2)
21977         local count
21978         local new_count
21979         local difference
21980         local i
21981         local rc
21982
21983         test_mkdir -p $DIR/$tdir
21984         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21985
21986         #test 10 returns only success/failure
21987         i=10
21988         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21989         rc=$?
21990         if [ $rc -eq 255 ]; then
21991                 error "Ladvise test${i} failed, ${rc}"
21992         fi
21993
21994         #test 11 counts lock enqueue requests, all others count new locks
21995         i=11
21996         count=$(do_facet ost1 \
21997                 $LCTL get_param -n ost.OSS.ost.stats)
21998         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21999
22000         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22001         rc=$?
22002         if [ $rc -eq 255 ]; then
22003                 error "Ladvise test${i} failed, ${rc}"
22004         fi
22005
22006         new_count=$(do_facet ost1 \
22007                 $LCTL get_param -n ost.OSS.ost.stats)
22008         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22009                    awk '{ print $2 }')
22010
22011         difference="$((new_count - count))"
22012         if [ $difference -ne $rc ]; then
22013                 error "Ladvise test${i}, bad enqueue count, returned " \
22014                       "${rc}, actual ${difference}"
22015         fi
22016
22017         for i in $(seq 12 21); do
22018                 # If we do not do this, we run the risk of having too many
22019                 # locks and starting lock cancellation while we are checking
22020                 # lock counts.
22021                 cancel_lru_locks osc
22022
22023                 count=$($LCTL get_param -n \
22024                        ldlm.namespaces.$imp_name.lock_unused_count)
22025
22026                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22027                 rc=$?
22028                 if [ $rc -eq 255 ]; then
22029                         error "Ladvise test ${i} failed, ${rc}"
22030                 fi
22031
22032                 new_count=$($LCTL get_param -n \
22033                        ldlm.namespaces.$imp_name.lock_unused_count)
22034                 difference="$((new_count - count))"
22035
22036                 # Test 15 output is divided by 100 to map down to valid return
22037                 if [ $i -eq 15 ]; then
22038                         rc="$((rc * 100))"
22039                 fi
22040
22041                 if [ $difference -ne $rc ]; then
22042                         error "Ladvise test ${i}, bad lock count, returned " \
22043                               "${rc}, actual ${difference}"
22044                 fi
22045         done
22046
22047         #test 22 returns only success/failure
22048         i=22
22049         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22050         rc=$?
22051         if [ $rc -eq 255 ]; then
22052                 error "Ladvise test${i} failed, ${rc}"
22053         fi
22054 }
22055 run_test 255c "suite of ladvise lockahead tests"
22056
22057 test_256() {
22058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22059         remote_mds_nodsh && skip "remote MDS with nodsh"
22060         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22061         changelog_users $SINGLEMDS | grep "^cl" &&
22062                 skip "active changelog user"
22063
22064         local cl_user
22065         local cat_sl
22066         local mdt_dev
22067
22068         mdt_dev=$(facet_device $SINGLEMDS)
22069         echo $mdt_dev
22070
22071         changelog_register || error "changelog_register failed"
22072
22073         rm -rf $DIR/$tdir
22074         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22075
22076         changelog_clear 0 || error "changelog_clear failed"
22077
22078         # change something
22079         touch $DIR/$tdir/{1..10}
22080
22081         # stop the MDT
22082         stop $SINGLEMDS || error "Fail to stop MDT"
22083
22084         # remount the MDT
22085         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22086                 error "Fail to start MDT"
22087
22088         #after mount new plainllog is used
22089         touch $DIR/$tdir/{11..19}
22090         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22091         stack_trap "rm -f $tmpfile"
22092         cat_sl=$(do_facet $SINGLEMDS "sync; \
22093                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22094                  llog_reader $tmpfile | grep -c type=1064553b")
22095         do_facet $SINGLEMDS llog_reader $tmpfile
22096
22097         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22098
22099         changelog_clear 0 || error "changelog_clear failed"
22100
22101         cat_sl=$(do_facet $SINGLEMDS "sync; \
22102                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22103                  llog_reader $tmpfile | grep -c type=1064553b")
22104
22105         if (( cat_sl == 2 )); then
22106                 error "Empty plain llog was not deleted from changelog catalog"
22107         elif (( cat_sl != 1 )); then
22108                 error "Active plain llog shouldn't be deleted from catalog"
22109         fi
22110 }
22111 run_test 256 "Check llog delete for empty and not full state"
22112
22113 test_257() {
22114         remote_mds_nodsh && skip "remote MDS with nodsh"
22115         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22116                 skip "Need MDS version at least 2.8.55"
22117
22118         test_mkdir $DIR/$tdir
22119
22120         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22121                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22122         stat $DIR/$tdir
22123
22124 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22125         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22126         local facet=mds$((mdtidx + 1))
22127         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22128         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22129
22130         stop $facet || error "stop MDS failed"
22131         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22132                 error "start MDS fail"
22133         wait_recovery_complete $facet
22134 }
22135 run_test 257 "xattr locks are not lost"
22136
22137 # Verify we take the i_mutex when security requires it
22138 test_258a() {
22139 #define OBD_FAIL_IMUTEX_SEC 0x141c
22140         $LCTL set_param fail_loc=0x141c
22141         touch $DIR/$tfile
22142         chmod u+s $DIR/$tfile
22143         chmod a+rwx $DIR/$tfile
22144         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22145         RC=$?
22146         if [ $RC -ne 0 ]; then
22147                 error "error, failed to take i_mutex, rc=$?"
22148         fi
22149         rm -f $DIR/$tfile
22150 }
22151 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22152
22153 # Verify we do NOT take the i_mutex in the normal case
22154 test_258b() {
22155 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22156         $LCTL set_param fail_loc=0x141d
22157         touch $DIR/$tfile
22158         chmod a+rwx $DIR
22159         chmod a+rw $DIR/$tfile
22160         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22161         RC=$?
22162         if [ $RC -ne 0 ]; then
22163                 error "error, took i_mutex unnecessarily, rc=$?"
22164         fi
22165         rm -f $DIR/$tfile
22166
22167 }
22168 run_test 258b "verify i_mutex security behavior"
22169
22170 test_259() {
22171         local file=$DIR/$tfile
22172         local before
22173         local after
22174
22175         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22176
22177         stack_trap "rm -f $file" EXIT
22178
22179         wait_delete_completed
22180         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22181         echo "before: $before"
22182
22183         $LFS setstripe -i 0 -c 1 $file
22184         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22185         sync_all_data
22186         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22187         echo "after write: $after"
22188
22189 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22190         do_facet ost1 $LCTL set_param fail_loc=0x2301
22191         $TRUNCATE $file 0
22192         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22193         echo "after truncate: $after"
22194
22195         stop ost1
22196         do_facet ost1 $LCTL set_param fail_loc=0
22197         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22198         sleep 2
22199         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22200         echo "after restart: $after"
22201         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22202                 error "missing truncate?"
22203
22204         return 0
22205 }
22206 run_test 259 "crash at delayed truncate"
22207
22208 test_260() {
22209 #define OBD_FAIL_MDC_CLOSE               0x806
22210         $LCTL set_param fail_loc=0x80000806
22211         touch $DIR/$tfile
22212
22213 }
22214 run_test 260 "Check mdc_close fail"
22215
22216 ### Data-on-MDT sanity tests ###
22217 test_270a() {
22218         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22219                 skip "Need MDS version at least 2.10.55 for DoM"
22220
22221         # create DoM file
22222         local dom=$DIR/$tdir/dom_file
22223         local tmp=$DIR/$tdir/tmp_file
22224
22225         mkdir_on_mdt0 $DIR/$tdir
22226
22227         # basic checks for DoM component creation
22228         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22229                 error "Can set MDT layout to non-first entry"
22230
22231         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22232                 error "Can define multiple entries as MDT layout"
22233
22234         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22235
22236         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22237         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22238         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22239
22240         local mdtidx=$($LFS getstripe -m $dom)
22241         local mdtname=MDT$(printf %04x $mdtidx)
22242         local facet=mds$((mdtidx + 1))
22243         local space_check=1
22244
22245         # Skip free space checks with ZFS
22246         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22247
22248         # write
22249         sync
22250         local size_tmp=$((65536 * 3))
22251         local mdtfree1=$(do_facet $facet \
22252                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22253
22254         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22255         # check also direct IO along write
22256         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22257         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22258         sync
22259         cmp $tmp $dom || error "file data is different"
22260         [ $(stat -c%s $dom) == $size_tmp ] ||
22261                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22262         if [ $space_check == 1 ]; then
22263                 local mdtfree2=$(do_facet $facet \
22264                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22265
22266                 # increase in usage from by $size_tmp
22267                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22268                         error "MDT free space wrong after write: " \
22269                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22270         fi
22271
22272         # truncate
22273         local size_dom=10000
22274
22275         $TRUNCATE $dom $size_dom
22276         [ $(stat -c%s $dom) == $size_dom ] ||
22277                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22278         if [ $space_check == 1 ]; then
22279                 mdtfree1=$(do_facet $facet \
22280                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22281                 # decrease in usage from $size_tmp to new $size_dom
22282                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22283                   $(((size_tmp - size_dom) / 1024)) ] ||
22284                         error "MDT free space is wrong after truncate: " \
22285                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22286         fi
22287
22288         # append
22289         cat $tmp >> $dom
22290         sync
22291         size_dom=$((size_dom + size_tmp))
22292         [ $(stat -c%s $dom) == $size_dom ] ||
22293                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22294         if [ $space_check == 1 ]; then
22295                 mdtfree2=$(do_facet $facet \
22296                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22297                 # increase in usage by $size_tmp from previous
22298                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22299                         error "MDT free space is wrong after append: " \
22300                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22301         fi
22302
22303         # delete
22304         rm $dom
22305         if [ $space_check == 1 ]; then
22306                 mdtfree1=$(do_facet $facet \
22307                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22308                 # decrease in usage by $size_dom from previous
22309                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22310                         error "MDT free space is wrong after removal: " \
22311                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22312         fi
22313
22314         # combined striping
22315         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22316                 error "Can't create DoM + OST striping"
22317
22318         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22319         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22320         # check also direct IO along write
22321         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22322         sync
22323         cmp $tmp $dom || error "file data is different"
22324         [ $(stat -c%s $dom) == $size_tmp ] ||
22325                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22326         rm $dom $tmp
22327
22328         return 0
22329 }
22330 run_test 270a "DoM: basic functionality tests"
22331
22332 test_270b() {
22333         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22334                 skip "Need MDS version at least 2.10.55"
22335
22336         local dom=$DIR/$tdir/dom_file
22337         local max_size=1048576
22338
22339         mkdir -p $DIR/$tdir
22340         $LFS setstripe -E $max_size -L mdt $dom
22341
22342         # truncate over the limit
22343         $TRUNCATE $dom $(($max_size + 1)) &&
22344                 error "successful truncate over the maximum size"
22345         # write over the limit
22346         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22347                 error "successful write over the maximum size"
22348         # append over the limit
22349         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22350         echo "12345" >> $dom && error "successful append over the maximum size"
22351         rm $dom
22352
22353         return 0
22354 }
22355 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22356
22357 test_270c() {
22358         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22359                 skip "Need MDS version at least 2.10.55"
22360
22361         mkdir -p $DIR/$tdir
22362         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22363
22364         # check files inherit DoM EA
22365         touch $DIR/$tdir/first
22366         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22367                 error "bad pattern"
22368         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22369                 error "bad stripe count"
22370         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22371                 error "bad stripe size"
22372
22373         # check directory inherits DoM EA and uses it as default
22374         mkdir $DIR/$tdir/subdir
22375         touch $DIR/$tdir/subdir/second
22376         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22377                 error "bad pattern in sub-directory"
22378         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22379                 error "bad stripe count in sub-directory"
22380         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22381                 error "bad stripe size in sub-directory"
22382         return 0
22383 }
22384 run_test 270c "DoM: DoM EA inheritance tests"
22385
22386 test_270d() {
22387         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22388                 skip "Need MDS version at least 2.10.55"
22389
22390         mkdir -p $DIR/$tdir
22391         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22392
22393         # inherit default DoM striping
22394         mkdir $DIR/$tdir/subdir
22395         touch $DIR/$tdir/subdir/f1
22396
22397         # change default directory striping
22398         $LFS setstripe -c 1 $DIR/$tdir/subdir
22399         touch $DIR/$tdir/subdir/f2
22400         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22401                 error "wrong default striping in file 2"
22402         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22403                 error "bad pattern in file 2"
22404         return 0
22405 }
22406 run_test 270d "DoM: change striping from DoM to RAID0"
22407
22408 test_270e() {
22409         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22410                 skip "Need MDS version at least 2.10.55"
22411
22412         mkdir -p $DIR/$tdir/dom
22413         mkdir -p $DIR/$tdir/norm
22414         DOMFILES=20
22415         NORMFILES=10
22416         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22417         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22418
22419         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22420         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22421
22422         # find DoM files by layout
22423         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22424         [ $NUM -eq  $DOMFILES ] ||
22425                 error "lfs find -L: found $NUM, expected $DOMFILES"
22426         echo "Test 1: lfs find 20 DOM files by layout: OK"
22427
22428         # there should be 1 dir with default DOM striping
22429         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22430         [ $NUM -eq  1 ] ||
22431                 error "lfs find -L: found $NUM, expected 1 dir"
22432         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22433
22434         # find DoM files by stripe size
22435         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22436         [ $NUM -eq  $DOMFILES ] ||
22437                 error "lfs find -S: found $NUM, expected $DOMFILES"
22438         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22439
22440         # find files by stripe offset except DoM files
22441         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22442         [ $NUM -eq  $NORMFILES ] ||
22443                 error "lfs find -i: found $NUM, expected $NORMFILES"
22444         echo "Test 5: lfs find no DOM files by stripe index: OK"
22445         return 0
22446 }
22447 run_test 270e "DoM: lfs find with DoM files test"
22448
22449 test_270f() {
22450         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22451                 skip "Need MDS version at least 2.10.55"
22452
22453         local mdtname=${FSNAME}-MDT0000-mdtlov
22454         local dom=$DIR/$tdir/dom_file
22455         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22456                                                 lod.$mdtname.dom_stripesize)
22457         local dom_limit=131072
22458
22459         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22460         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22461                                                 lod.$mdtname.dom_stripesize)
22462         [ ${dom_limit} -eq ${dom_current} ] ||
22463                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22464
22465         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22466         $LFS setstripe -d $DIR/$tdir
22467         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22468                 error "Can't set directory default striping"
22469
22470         # exceed maximum stripe size
22471         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22472                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22473         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22474                 error "Able to create DoM component size more than LOD limit"
22475
22476         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22477         dom_current=$(do_facet mds1 $LCTL get_param -n \
22478                                                 lod.$mdtname.dom_stripesize)
22479         [ 0 -eq ${dom_current} ] ||
22480                 error "Can't set zero DoM stripe limit"
22481         rm $dom
22482
22483         # attempt to create DoM file on server with disabled DoM should
22484         # remove DoM entry from layout and be succeed
22485         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22486                 error "Can't create DoM file (DoM is disabled)"
22487         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22488                 error "File has DoM component while DoM is disabled"
22489         rm $dom
22490
22491         # attempt to create DoM file with only DoM stripe should return error
22492         $LFS setstripe -E $dom_limit -L mdt $dom &&
22493                 error "Able to create DoM-only file while DoM is disabled"
22494
22495         # too low values to be aligned with smallest stripe size 64K
22496         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22497         dom_current=$(do_facet mds1 $LCTL get_param -n \
22498                                                 lod.$mdtname.dom_stripesize)
22499         [ 30000 -eq ${dom_current} ] &&
22500                 error "Can set too small DoM stripe limit"
22501
22502         # 64K is a minimal stripe size in Lustre, expect limit of that size
22503         [ 65536 -eq ${dom_current} ] ||
22504                 error "Limit is not set to 64K but ${dom_current}"
22505
22506         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22507         dom_current=$(do_facet mds1 $LCTL get_param -n \
22508                                                 lod.$mdtname.dom_stripesize)
22509         echo $dom_current
22510         [ 2147483648 -eq ${dom_current} ] &&
22511                 error "Can set too large DoM stripe limit"
22512
22513         do_facet mds1 $LCTL set_param -n \
22514                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22515         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22516                 error "Can't create DoM component size after limit change"
22517         do_facet mds1 $LCTL set_param -n \
22518                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22519         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22520                 error "Can't create DoM file after limit decrease"
22521         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22522                 error "Can create big DoM component after limit decrease"
22523         touch ${dom}_def ||
22524                 error "Can't create file with old default layout"
22525
22526         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22527         return 0
22528 }
22529 run_test 270f "DoM: maximum DoM stripe size checks"
22530
22531 test_270g() {
22532         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22533                 skip "Need MDS version at least 2.13.52"
22534         local dom=$DIR/$tdir/$tfile
22535
22536         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22537         local lodname=${FSNAME}-MDT0000-mdtlov
22538
22539         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22540         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22541         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22542         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22543
22544         local dom_limit=1024
22545         local dom_threshold="50%"
22546
22547         $LFS setstripe -d $DIR/$tdir
22548         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22549                 error "Can't set directory default striping"
22550
22551         do_facet mds1 $LCTL set_param -n \
22552                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22553         # set 0 threshold and create DOM file to change tunable stripesize
22554         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22555         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22556                 error "Failed to create $dom file"
22557         # now tunable dom_cur_stripesize should reach maximum
22558         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22559                                         lod.${lodname}.dom_stripesize_cur_kb)
22560         [[ $dom_current == $dom_limit ]] ||
22561                 error "Current DOM stripesize is not maximum"
22562         rm $dom
22563
22564         # set threshold for further tests
22565         do_facet mds1 $LCTL set_param -n \
22566                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22567         echo "DOM threshold is $dom_threshold free space"
22568         local dom_def
22569         local dom_set
22570         # Spoof bfree to exceed threshold
22571         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22572         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22573         for spfree in 40 20 0 15 30 55; do
22574                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22575                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22576                         error "Failed to create $dom file"
22577                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22578                                         lod.${lodname}.dom_stripesize_cur_kb)
22579                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22580                 [[ $dom_def != $dom_current ]] ||
22581                         error "Default stripe size was not changed"
22582                 if (( spfree > 0 )) ; then
22583                         dom_set=$($LFS getstripe -S $dom)
22584                         (( dom_set == dom_def * 1024 )) ||
22585                                 error "DOM component size is still old"
22586                 else
22587                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22588                                 error "DoM component is set with no free space"
22589                 fi
22590                 rm $dom
22591                 dom_current=$dom_def
22592         done
22593 }
22594 run_test 270g "DoM: default DoM stripe size depends on free space"
22595
22596 test_270h() {
22597         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22598                 skip "Need MDS version at least 2.13.53"
22599
22600         local mdtname=${FSNAME}-MDT0000-mdtlov
22601         local dom=$DIR/$tdir/$tfile
22602         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22603
22604         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22605         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22606
22607         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22608         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22609                 error "can't create OST file"
22610         # mirrored file with DOM entry in the second mirror
22611         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22612                 error "can't create mirror with DoM component"
22613
22614         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22615
22616         # DOM component in the middle and has other enries in the same mirror,
22617         # should succeed but lost DoM component
22618         $LFS setstripe --copy=${dom}_1 $dom ||
22619                 error "Can't create file from OST|DOM mirror layout"
22620         # check new file has no DoM layout after all
22621         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22622                 error "File has DoM component while DoM is disabled"
22623 }
22624 run_test 270h "DoM: DoM stripe removal when disabled on server"
22625
22626 test_270i() {
22627         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22628                 skip "Need MDS version at least 2.14.54"
22629
22630         mkdir $DIR/$tdir
22631         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22632                 error "setstripe should fail" || true
22633 }
22634 run_test 270i "DoM: setting invalid DoM striping should fail"
22635
22636 test_271a() {
22637         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22638                 skip "Need MDS version at least 2.10.55"
22639
22640         local dom=$DIR/$tdir/dom
22641
22642         mkdir -p $DIR/$tdir
22643
22644         $LFS setstripe -E 1024K -L mdt $dom
22645
22646         lctl set_param -n mdc.*.stats=clear
22647         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22648         cat $dom > /dev/null
22649         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22650         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22651         ls $dom
22652         rm -f $dom
22653 }
22654 run_test 271a "DoM: data is cached for read after write"
22655
22656 test_271b() {
22657         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22658                 skip "Need MDS version at least 2.10.55"
22659
22660         local dom=$DIR/$tdir/dom
22661
22662         mkdir -p $DIR/$tdir
22663
22664         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22665
22666         lctl set_param -n mdc.*.stats=clear
22667         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22668         cancel_lru_locks mdc
22669         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22670         # second stat to check size is cached on client
22671         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22672         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22673         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22674         rm -f $dom
22675 }
22676 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22677
22678 test_271ba() {
22679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22680                 skip "Need MDS version at least 2.10.55"
22681
22682         local dom=$DIR/$tdir/dom
22683
22684         mkdir -p $DIR/$tdir
22685
22686         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22687
22688         lctl set_param -n mdc.*.stats=clear
22689         lctl set_param -n osc.*.stats=clear
22690         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22691         cancel_lru_locks mdc
22692         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22693         # second stat to check size is cached on client
22694         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22695         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22696         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22697         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22698         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22699         rm -f $dom
22700 }
22701 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22702
22703
22704 get_mdc_stats() {
22705         local mdtidx=$1
22706         local param=$2
22707         local mdt=MDT$(printf %04x $mdtidx)
22708
22709         if [ -z $param ]; then
22710                 lctl get_param -n mdc.*$mdt*.stats
22711         else
22712                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22713         fi
22714 }
22715
22716 test_271c() {
22717         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22718                 skip "Need MDS version at least 2.10.55"
22719
22720         local dom=$DIR/$tdir/dom
22721
22722         mkdir -p $DIR/$tdir
22723
22724         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22725
22726         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22727         local facet=mds$((mdtidx + 1))
22728
22729         cancel_lru_locks mdc
22730         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22731         createmany -o $dom 1000
22732         lctl set_param -n mdc.*.stats=clear
22733         smalliomany -w $dom 1000 200
22734         get_mdc_stats $mdtidx
22735         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22736         # Each file has 1 open, 1 IO enqueues, total 2000
22737         # but now we have also +1 getxattr for security.capability, total 3000
22738         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22739         unlinkmany $dom 1000
22740
22741         cancel_lru_locks mdc
22742         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22743         createmany -o $dom 1000
22744         lctl set_param -n mdc.*.stats=clear
22745         smalliomany -w $dom 1000 200
22746         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22747         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22748         # for OPEN and IO lock.
22749         [ $((enq - enq_2)) -ge 1000 ] ||
22750                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22751         unlinkmany $dom 1000
22752         return 0
22753 }
22754 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22755
22756 cleanup_271def_tests() {
22757         trap 0
22758         rm -f $1
22759 }
22760
22761 test_271d() {
22762         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22763                 skip "Need MDS version at least 2.10.57"
22764
22765         local dom=$DIR/$tdir/dom
22766         local tmp=$TMP/$tfile
22767         trap "cleanup_271def_tests $tmp" EXIT
22768
22769         mkdir -p $DIR/$tdir
22770
22771         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22772
22773         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22774
22775         cancel_lru_locks mdc
22776         dd if=/dev/urandom of=$tmp bs=1000 count=1
22777         dd if=$tmp of=$dom bs=1000 count=1
22778         cancel_lru_locks mdc
22779
22780         cat /etc/hosts >> $tmp
22781         lctl set_param -n mdc.*.stats=clear
22782
22783         # append data to the same file it should update local page
22784         echo "Append to the same page"
22785         cat /etc/hosts >> $dom
22786         local num=$(get_mdc_stats $mdtidx ost_read)
22787         local ra=$(get_mdc_stats $mdtidx req_active)
22788         local rw=$(get_mdc_stats $mdtidx req_waittime)
22789
22790         [ -z $num ] || error "$num READ RPC occured"
22791         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22792         echo "... DONE"
22793
22794         # compare content
22795         cmp $tmp $dom || error "file miscompare"
22796
22797         cancel_lru_locks mdc
22798         lctl set_param -n mdc.*.stats=clear
22799
22800         echo "Open and read file"
22801         cat $dom > /dev/null
22802         local num=$(get_mdc_stats $mdtidx ost_read)
22803         local ra=$(get_mdc_stats $mdtidx req_active)
22804         local rw=$(get_mdc_stats $mdtidx req_waittime)
22805
22806         [ -z $num ] || error "$num READ RPC occured"
22807         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22808         echo "... DONE"
22809
22810         # compare content
22811         cmp $tmp $dom || error "file miscompare"
22812
22813         return 0
22814 }
22815 run_test 271d "DoM: read on open (1K file in reply buffer)"
22816
22817 test_271f() {
22818         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22819                 skip "Need MDS version at least 2.10.57"
22820
22821         local dom=$DIR/$tdir/dom
22822         local tmp=$TMP/$tfile
22823         trap "cleanup_271def_tests $tmp" EXIT
22824
22825         mkdir -p $DIR/$tdir
22826
22827         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22828
22829         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22830
22831         cancel_lru_locks mdc
22832         dd if=/dev/urandom of=$tmp bs=265000 count=1
22833         dd if=$tmp of=$dom bs=265000 count=1
22834         cancel_lru_locks mdc
22835         cat /etc/hosts >> $tmp
22836         lctl set_param -n mdc.*.stats=clear
22837
22838         echo "Append to the same page"
22839         cat /etc/hosts >> $dom
22840         local num=$(get_mdc_stats $mdtidx ost_read)
22841         local ra=$(get_mdc_stats $mdtidx req_active)
22842         local rw=$(get_mdc_stats $mdtidx req_waittime)
22843
22844         [ -z $num ] || error "$num READ RPC occured"
22845         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22846         echo "... DONE"
22847
22848         # compare content
22849         cmp $tmp $dom || error "file miscompare"
22850
22851         cancel_lru_locks mdc
22852         lctl set_param -n mdc.*.stats=clear
22853
22854         echo "Open and read file"
22855         cat $dom > /dev/null
22856         local num=$(get_mdc_stats $mdtidx ost_read)
22857         local ra=$(get_mdc_stats $mdtidx req_active)
22858         local rw=$(get_mdc_stats $mdtidx req_waittime)
22859
22860         [ -z $num ] && num=0
22861         [ $num -eq 1 ] || error "expect 1 READ RPC, $num 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         return 0
22869 }
22870 run_test 271f "DoM: read on open (200K file and read tail)"
22871
22872 test_271g() {
22873         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22874                 skip "Skipping due to old client or server version"
22875
22876         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22877         # to get layout
22878         $CHECKSTAT -t file $DIR1/$tfile
22879
22880         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22881         MULTIOP_PID=$!
22882         sleep 1
22883         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22884         $LCTL set_param fail_loc=0x80000314
22885         rm $DIR1/$tfile || error "Unlink fails"
22886         RC=$?
22887         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22888         [ $RC -eq 0 ] || error "Failed write to stale object"
22889 }
22890 run_test 271g "Discard DoM data vs client flush race"
22891
22892 test_272a() {
22893         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22894                 skip "Need MDS version at least 2.11.50"
22895
22896         local dom=$DIR/$tdir/dom
22897         mkdir -p $DIR/$tdir
22898
22899         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22900         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22901                 error "failed to write data into $dom"
22902         local old_md5=$(md5sum $dom)
22903
22904         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22905                 error "failed to migrate to the same DoM component"
22906
22907         local new_md5=$(md5sum $dom)
22908
22909         [ "$old_md5" == "$new_md5" ] ||
22910                 error "md5sum differ: $old_md5, $new_md5"
22911
22912         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22913                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22914 }
22915 run_test 272a "DoM migration: new layout with the same DOM component"
22916
22917 test_272b() {
22918         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22919                 skip "Need MDS version at least 2.11.50"
22920
22921         local dom=$DIR/$tdir/dom
22922         mkdir -p $DIR/$tdir
22923         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22924
22925         local mdtidx=$($LFS getstripe -m $dom)
22926         local mdtname=MDT$(printf %04x $mdtidx)
22927         local facet=mds$((mdtidx + 1))
22928
22929         local mdtfree1=$(do_facet $facet \
22930                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22931         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22932                 error "failed to write data into $dom"
22933         local old_md5=$(md5sum $dom)
22934         cancel_lru_locks mdc
22935         local mdtfree1=$(do_facet $facet \
22936                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22937
22938         $LFS migrate -c2 $dom ||
22939                 error "failed to migrate to the new composite layout"
22940         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22941                 error "MDT stripe was not removed"
22942
22943         cancel_lru_locks mdc
22944         local new_md5=$(md5sum $dom)
22945         [ "$old_md5" == "$new_md5" ] ||
22946                 error "$old_md5 != $new_md5"
22947
22948         # Skip free space checks with ZFS
22949         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22950                 local mdtfree2=$(do_facet $facet \
22951                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22952                 [ $mdtfree2 -gt $mdtfree1 ] ||
22953                         error "MDT space is not freed after migration"
22954         fi
22955         return 0
22956 }
22957 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22958
22959 test_272c() {
22960         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22961                 skip "Need MDS version at least 2.11.50"
22962
22963         local dom=$DIR/$tdir/$tfile
22964         mkdir -p $DIR/$tdir
22965         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22966
22967         local mdtidx=$($LFS getstripe -m $dom)
22968         local mdtname=MDT$(printf %04x $mdtidx)
22969         local facet=mds$((mdtidx + 1))
22970
22971         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22972                 error "failed to write data into $dom"
22973         local old_md5=$(md5sum $dom)
22974         cancel_lru_locks mdc
22975         local mdtfree1=$(do_facet $facet \
22976                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22977
22978         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22979                 error "failed to migrate to the new composite layout"
22980         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22981                 error "MDT stripe was not removed"
22982
22983         cancel_lru_locks mdc
22984         local new_md5=$(md5sum $dom)
22985         [ "$old_md5" == "$new_md5" ] ||
22986                 error "$old_md5 != $new_md5"
22987
22988         # Skip free space checks with ZFS
22989         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22990                 local mdtfree2=$(do_facet $facet \
22991                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22992                 [ $mdtfree2 -gt $mdtfree1 ] ||
22993                         error "MDS space is not freed after migration"
22994         fi
22995         return 0
22996 }
22997 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22998
22999 test_272d() {
23000         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23001                 skip "Need MDS version at least 2.12.55"
23002
23003         local dom=$DIR/$tdir/$tfile
23004         mkdir -p $DIR/$tdir
23005         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23006
23007         local mdtidx=$($LFS getstripe -m $dom)
23008         local mdtname=MDT$(printf %04x $mdtidx)
23009         local facet=mds$((mdtidx + 1))
23010
23011         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23012                 error "failed to write data into $dom"
23013         local old_md5=$(md5sum $dom)
23014         cancel_lru_locks mdc
23015         local mdtfree1=$(do_facet $facet \
23016                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23017
23018         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23019                 error "failed mirroring to the new composite layout"
23020         $LFS mirror resync $dom ||
23021                 error "failed mirror resync"
23022         $LFS mirror split --mirror-id 1 -d $dom ||
23023                 error "failed mirror split"
23024
23025         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23026                 error "MDT stripe was not removed"
23027
23028         cancel_lru_locks mdc
23029         local new_md5=$(md5sum $dom)
23030         [ "$old_md5" == "$new_md5" ] ||
23031                 error "$old_md5 != $new_md5"
23032
23033         # Skip free space checks with ZFS
23034         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23035                 local mdtfree2=$(do_facet $facet \
23036                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23037                 [ $mdtfree2 -gt $mdtfree1 ] ||
23038                         error "MDS space is not freed after DOM mirror deletion"
23039         fi
23040         return 0
23041 }
23042 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23043
23044 test_272e() {
23045         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23046                 skip "Need MDS version at least 2.12.55"
23047
23048         local dom=$DIR/$tdir/$tfile
23049         mkdir -p $DIR/$tdir
23050         $LFS setstripe -c 2 $dom
23051
23052         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23053                 error "failed to write data into $dom"
23054         local old_md5=$(md5sum $dom)
23055         cancel_lru_locks
23056
23057         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23058                 error "failed mirroring to the DOM layout"
23059         $LFS mirror resync $dom ||
23060                 error "failed mirror resync"
23061         $LFS mirror split --mirror-id 1 -d $dom ||
23062                 error "failed mirror split"
23063
23064         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23065                 error "MDT stripe wasn't set"
23066
23067         cancel_lru_locks
23068         local new_md5=$(md5sum $dom)
23069         [ "$old_md5" == "$new_md5" ] ||
23070                 error "$old_md5 != $new_md5"
23071
23072         return 0
23073 }
23074 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23075
23076 test_272f() {
23077         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23078                 skip "Need MDS version at least 2.12.55"
23079
23080         local dom=$DIR/$tdir/$tfile
23081         mkdir -p $DIR/$tdir
23082         $LFS setstripe -c 2 $dom
23083
23084         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23085                 error "failed to write data into $dom"
23086         local old_md5=$(md5sum $dom)
23087         cancel_lru_locks
23088
23089         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23090                 error "failed migrating to the DOM file"
23091
23092         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23093                 error "MDT stripe wasn't set"
23094
23095         cancel_lru_locks
23096         local new_md5=$(md5sum $dom)
23097         [ "$old_md5" != "$new_md5" ] &&
23098                 error "$old_md5 != $new_md5"
23099
23100         return 0
23101 }
23102 run_test 272f "DoM migration: OST-striped file to DOM file"
23103
23104 test_273a() {
23105         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23106                 skip "Need MDS version at least 2.11.50"
23107
23108         # Layout swap cannot be done if either file has DOM component,
23109         # this will never be supported, migration should be used instead
23110
23111         local dom=$DIR/$tdir/$tfile
23112         mkdir -p $DIR/$tdir
23113
23114         $LFS setstripe -c2 ${dom}_plain
23115         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23116         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23117                 error "can swap layout with DoM component"
23118         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23119                 error "can swap layout with DoM component"
23120
23121         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23122         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23123                 error "can swap layout with DoM component"
23124         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23125                 error "can swap layout with DoM component"
23126         return 0
23127 }
23128 run_test 273a "DoM: layout swapping should fail with DOM"
23129
23130 test_273b() {
23131         mkdir -p $DIR/$tdir
23132         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23133
23134 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23135         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23136
23137         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23138 }
23139 run_test 273b "DoM: race writeback and object destroy"
23140
23141 test_275() {
23142         remote_ost_nodsh && skip "remote OST with nodsh"
23143         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23144                 skip "Need OST version >= 2.10.57"
23145
23146         local file=$DIR/$tfile
23147         local oss
23148
23149         oss=$(comma_list $(osts_nodes))
23150
23151         dd if=/dev/urandom of=$file bs=1M count=2 ||
23152                 error "failed to create a file"
23153         cancel_lru_locks osc
23154
23155         #lock 1
23156         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23157                 error "failed to read a file"
23158
23159 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23160         $LCTL set_param fail_loc=0x8000031f
23161
23162         cancel_lru_locks osc &
23163         sleep 1
23164
23165 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23166         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23167         #IO takes another lock, but matches the PENDING one
23168         #and places it to the IO RPC
23169         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23170                 error "failed to read a file with PENDING lock"
23171 }
23172 run_test 275 "Read on a canceled duplicate lock"
23173
23174 test_276() {
23175         remote_ost_nodsh && skip "remote OST with nodsh"
23176         local pid
23177
23178         do_facet ost1 "(while true; do \
23179                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23180                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23181         pid=$!
23182
23183         for LOOP in $(seq 20); do
23184                 stop ost1
23185                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23186         done
23187         kill -9 $pid
23188         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23189                 rm $TMP/sanity_276_pid"
23190 }
23191 run_test 276 "Race between mount and obd_statfs"
23192
23193 test_277() {
23194         $LCTL set_param ldlm.namespaces.*.lru_size=0
23195         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23196         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23197                         grep ^used_mb | awk '{print $2}')
23198         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23200                 oflag=direct conv=notrunc
23201         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23202                         grep ^used_mb | awk '{print $2}')
23203         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23204 }
23205 run_test 277 "Direct IO shall drop page cache"
23206
23207 test_278() {
23208         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23209         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23210         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23211                 skip "needs the same host for mdt1 mdt2" && return
23212
23213         local pid1
23214         local pid2
23215
23216 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23217         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23218         stop mds2 &
23219         pid2=$!
23220
23221         stop mds1
23222
23223         echo "Starting MDTs"
23224         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23225         wait $pid2
23226 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23227 #will return NULL
23228         do_facet mds2 $LCTL set_param fail_loc=0
23229
23230         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23231         wait_recovery_complete mds2
23232 }
23233 run_test 278 "Race starting MDS between MDTs stop/start"
23234
23235 test_280() {
23236         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23237                 skip "Need MGS version at least 2.13.52"
23238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23239         combined_mgs_mds || skip "needs combined MGS/MDT"
23240
23241         umount_client $MOUNT
23242 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23243         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23244
23245         mount_client $MOUNT &
23246         sleep 1
23247         stop mgs || error "stop mgs failed"
23248         #for a race mgs would crash
23249         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23250         # make sure we unmount client before remounting
23251         wait
23252         umount_client $MOUNT
23253         mount_client $MOUNT || error "mount client failed"
23254 }
23255 run_test 280 "Race between MGS umount and client llog processing"
23256
23257 cleanup_test_300() {
23258         trap 0
23259         umask $SAVE_UMASK
23260 }
23261 test_striped_dir() {
23262         local mdt_index=$1
23263         local stripe_count
23264         local stripe_index
23265
23266         mkdir -p $DIR/$tdir
23267
23268         SAVE_UMASK=$(umask)
23269         trap cleanup_test_300 RETURN EXIT
23270
23271         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23272                                                 $DIR/$tdir/striped_dir ||
23273                 error "set striped dir error"
23274
23275         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23276         [ "$mode" = "755" ] || error "expect 755 got $mode"
23277
23278         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23279                 error "getdirstripe failed"
23280         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23281         if [ "$stripe_count" != "2" ]; then
23282                 error "1:stripe_count is $stripe_count, expect 2"
23283         fi
23284         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23285         if [ "$stripe_count" != "2" ]; then
23286                 error "2:stripe_count is $stripe_count, expect 2"
23287         fi
23288
23289         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23290         if [ "$stripe_index" != "$mdt_index" ]; then
23291                 error "stripe_index is $stripe_index, expect $mdt_index"
23292         fi
23293
23294         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23295                 error "nlink error after create striped dir"
23296
23297         mkdir $DIR/$tdir/striped_dir/a
23298         mkdir $DIR/$tdir/striped_dir/b
23299
23300         stat $DIR/$tdir/striped_dir/a ||
23301                 error "create dir under striped dir failed"
23302         stat $DIR/$tdir/striped_dir/b ||
23303                 error "create dir under striped dir failed"
23304
23305         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23306                 error "nlink error after mkdir"
23307
23308         rmdir $DIR/$tdir/striped_dir/a
23309         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23310                 error "nlink error after rmdir"
23311
23312         rmdir $DIR/$tdir/striped_dir/b
23313         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23314                 error "nlink error after rmdir"
23315
23316         chattr +i $DIR/$tdir/striped_dir
23317         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23318                 error "immutable flags not working under striped dir!"
23319         chattr -i $DIR/$tdir/striped_dir
23320
23321         rmdir $DIR/$tdir/striped_dir ||
23322                 error "rmdir striped dir error"
23323
23324         cleanup_test_300
23325
23326         true
23327 }
23328
23329 test_300a() {
23330         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23331                 skip "skipped for lustre < 2.7.0"
23332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23334
23335         test_striped_dir 0 || error "failed on striped dir on MDT0"
23336         test_striped_dir 1 || error "failed on striped dir on MDT0"
23337 }
23338 run_test 300a "basic striped dir sanity test"
23339
23340 test_300b() {
23341         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23342                 skip "skipped for lustre < 2.7.0"
23343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23345
23346         local i
23347         local mtime1
23348         local mtime2
23349         local mtime3
23350
23351         test_mkdir $DIR/$tdir || error "mkdir fail"
23352         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23353                 error "set striped dir error"
23354         for i in {0..9}; do
23355                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23356                 sleep 1
23357                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23358                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23359                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23360                 sleep 1
23361                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23362                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23363                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23364         done
23365         true
23366 }
23367 run_test 300b "check ctime/mtime for striped dir"
23368
23369 test_300c() {
23370         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23371                 skip "skipped for lustre < 2.7.0"
23372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23374
23375         local file_count
23376
23377         mkdir_on_mdt0 $DIR/$tdir
23378         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23379                 error "set striped dir error"
23380
23381         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23382                 error "chown striped dir failed"
23383
23384         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23385                 error "create 5k files failed"
23386
23387         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23388
23389         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23390
23391         rm -rf $DIR/$tdir
23392 }
23393 run_test 300c "chown && check ls under striped directory"
23394
23395 test_300d() {
23396         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23397                 skip "skipped for lustre < 2.7.0"
23398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23400
23401         local stripe_count
23402         local file
23403
23404         mkdir -p $DIR/$tdir
23405         $LFS setstripe -c 2 $DIR/$tdir
23406
23407         #local striped directory
23408         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23409                 error "set striped dir error"
23410         #look at the directories for debug purposes
23411         ls -l $DIR/$tdir
23412         $LFS getdirstripe $DIR/$tdir
23413         ls -l $DIR/$tdir/striped_dir
23414         $LFS getdirstripe $DIR/$tdir/striped_dir
23415         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23416                 error "create 10 files failed"
23417
23418         #remote striped directory
23419         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23420                 error "set striped dir error"
23421         #look at the directories for debug purposes
23422         ls -l $DIR/$tdir
23423         $LFS getdirstripe $DIR/$tdir
23424         ls -l $DIR/$tdir/remote_striped_dir
23425         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23426         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23427                 error "create 10 files failed"
23428
23429         for file in $(find $DIR/$tdir); do
23430                 stripe_count=$($LFS getstripe -c $file)
23431                 [ $stripe_count -eq 2 ] ||
23432                         error "wrong stripe $stripe_count for $file"
23433         done
23434
23435         rm -rf $DIR/$tdir
23436 }
23437 run_test 300d "check default stripe under striped directory"
23438
23439 test_300e() {
23440         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23441                 skip "Need MDS version at least 2.7.55"
23442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23444
23445         local stripe_count
23446         local file
23447
23448         mkdir -p $DIR/$tdir
23449
23450         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23451                 error "set striped dir error"
23452
23453         touch $DIR/$tdir/striped_dir/a
23454         touch $DIR/$tdir/striped_dir/b
23455         touch $DIR/$tdir/striped_dir/c
23456
23457         mkdir $DIR/$tdir/striped_dir/dir_a
23458         mkdir $DIR/$tdir/striped_dir/dir_b
23459         mkdir $DIR/$tdir/striped_dir/dir_c
23460
23461         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23462                 error "set striped adir under striped dir error"
23463
23464         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23465                 error "set striped bdir under striped dir error"
23466
23467         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23468                 error "set striped cdir under striped dir error"
23469
23470         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23471                 error "rename dir under striped dir fails"
23472
23473         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23474                 error "rename dir under different stripes fails"
23475
23476         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23477                 error "rename file under striped dir should succeed"
23478
23479         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23480                 error "rename dir under striped dir should succeed"
23481
23482         rm -rf $DIR/$tdir
23483 }
23484 run_test 300e "check rename under striped directory"
23485
23486 test_300f() {
23487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23489         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23490                 skip "Need MDS version at least 2.7.55"
23491
23492         local stripe_count
23493         local file
23494
23495         rm -rf $DIR/$tdir
23496         mkdir -p $DIR/$tdir
23497
23498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23499                 error "set striped dir error"
23500
23501         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23502                 error "set striped dir error"
23503
23504         touch $DIR/$tdir/striped_dir/a
23505         mkdir $DIR/$tdir/striped_dir/dir_a
23506         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23507                 error "create striped dir under striped dir fails"
23508
23509         touch $DIR/$tdir/striped_dir1/b
23510         mkdir $DIR/$tdir/striped_dir1/dir_b
23511         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23512                 error "create striped dir under striped dir fails"
23513
23514         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23515                 error "rename dir under different striped dir should fail"
23516
23517         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23518                 error "rename striped dir under diff striped dir should fail"
23519
23520         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23521                 error "rename file under diff striped dirs fails"
23522
23523         rm -rf $DIR/$tdir
23524 }
23525 run_test 300f "check rename cross striped directory"
23526
23527 test_300_check_default_striped_dir()
23528 {
23529         local dirname=$1
23530         local default_count=$2
23531         local default_index=$3
23532         local stripe_count
23533         local stripe_index
23534         local dir_stripe_index
23535         local dir
23536
23537         echo "checking $dirname $default_count $default_index"
23538         $LFS setdirstripe -D -c $default_count -i $default_index \
23539                                 -H all_char $DIR/$tdir/$dirname ||
23540                 error "set default stripe on striped dir error"
23541         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23542         [ $stripe_count -eq $default_count ] ||
23543                 error "expect $default_count get $stripe_count for $dirname"
23544
23545         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23546         [ $stripe_index -eq $default_index ] ||
23547                 error "expect $default_index get $stripe_index for $dirname"
23548
23549         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23550                                                 error "create dirs failed"
23551
23552         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23553         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23554         for dir in $(find $DIR/$tdir/$dirname/*); do
23555                 stripe_count=$($LFS getdirstripe -c $dir)
23556                 (( $stripe_count == $default_count )) ||
23557                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23558                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23559                 error "stripe count $default_count != $stripe_count for $dir"
23560
23561                 stripe_index=$($LFS getdirstripe -i $dir)
23562                 [ $default_index -eq -1 ] ||
23563                         [ $stripe_index -eq $default_index ] ||
23564                         error "$stripe_index != $default_index for $dir"
23565
23566                 #check default stripe
23567                 stripe_count=$($LFS getdirstripe -D -c $dir)
23568                 [ $stripe_count -eq $default_count ] ||
23569                 error "default count $default_count != $stripe_count for $dir"
23570
23571                 stripe_index=$($LFS getdirstripe -D -i $dir)
23572                 [ $stripe_index -eq $default_index ] ||
23573                 error "default index $default_index != $stripe_index for $dir"
23574         done
23575         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23576 }
23577
23578 test_300g() {
23579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23580         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23581                 skip "Need MDS version at least 2.7.55"
23582
23583         local dir
23584         local stripe_count
23585         local stripe_index
23586
23587         mkdir_on_mdt0 $DIR/$tdir
23588         mkdir $DIR/$tdir/normal_dir
23589
23590         #Checking when client cache stripe index
23591         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23592         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23593                 error "create striped_dir failed"
23594
23595         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23596                 error "create dir0 fails"
23597         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23598         [ $stripe_index -eq 0 ] ||
23599                 error "dir0 expect index 0 got $stripe_index"
23600
23601         mkdir $DIR/$tdir/striped_dir/dir1 ||
23602                 error "create dir1 fails"
23603         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23604         [ $stripe_index -eq 1 ] ||
23605                 error "dir1 expect index 1 got $stripe_index"
23606
23607         #check default stripe count/stripe index
23608         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23609         test_300_check_default_striped_dir normal_dir 1 0
23610         test_300_check_default_striped_dir normal_dir -1 1
23611         test_300_check_default_striped_dir normal_dir 2 -1
23612
23613         #delete default stripe information
23614         echo "delete default stripeEA"
23615         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23616                 error "set default stripe on striped dir error"
23617
23618         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23619         for dir in $(find $DIR/$tdir/normal_dir/*); do
23620                 stripe_count=$($LFS getdirstripe -c $dir)
23621                 [ $stripe_count -eq 0 ] ||
23622                         error "expect 1 get $stripe_count for $dir"
23623         done
23624 }
23625 run_test 300g "check default striped directory for normal directory"
23626
23627 test_300h() {
23628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23629         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23630                 skip "Need MDS version at least 2.7.55"
23631
23632         local dir
23633         local stripe_count
23634
23635         mkdir $DIR/$tdir
23636         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23637                 error "set striped dir error"
23638
23639         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23640         test_300_check_default_striped_dir striped_dir 1 0
23641         test_300_check_default_striped_dir striped_dir -1 1
23642         test_300_check_default_striped_dir striped_dir 2 -1
23643
23644         #delete default stripe information
23645         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23646                 error "set default stripe on striped dir error"
23647
23648         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23649         for dir in $(find $DIR/$tdir/striped_dir/*); do
23650                 stripe_count=$($LFS getdirstripe -c $dir)
23651                 [ $stripe_count -eq 0 ] ||
23652                         error "expect 1 get $stripe_count for $dir"
23653         done
23654 }
23655 run_test 300h "check default striped directory for striped directory"
23656
23657 test_300i() {
23658         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23659         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23660         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23661                 skip "Need MDS version at least 2.7.55"
23662
23663         local stripe_count
23664         local file
23665
23666         mkdir $DIR/$tdir
23667
23668         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23669                 error "set striped dir error"
23670
23671         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23672                 error "create files under striped dir failed"
23673
23674         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23675                 error "set striped hashdir error"
23676
23677         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23678                 error "create dir0 under hash dir failed"
23679         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23680                 error "create dir1 under hash dir failed"
23681         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23682                 error "create dir2 under hash dir failed"
23683
23684         # unfortunately, we need to umount to clear dir layout cache for now
23685         # once we fully implement dir layout, we can drop this
23686         umount_client $MOUNT || error "umount failed"
23687         mount_client $MOUNT || error "mount failed"
23688
23689         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23690         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23691         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23692
23693         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23694                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23695                         error "create crush2 dir $tdir/hashdir/d3 failed"
23696                 $LFS find -H crush2 $DIR/$tdir/hashdir
23697                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23698                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23699
23700                 # mkdir with an invalid hash type (hash=fail_val) from client
23701                 # should be replaced on MDS with a valid (default) hash type
23702                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23703                 $LCTL set_param fail_loc=0x1901 fail_val=99
23704                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23705
23706                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23707                 local expect=$(do_facet mds1 \
23708                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23709                 [[ $hash == $expect ]] ||
23710                         error "d99 hash '$hash' != expected hash '$expect'"
23711         fi
23712
23713         #set the stripe to be unknown hash type on read
23714         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23715         $LCTL set_param fail_loc=0x1901 fail_val=99
23716         for ((i = 0; i < 10; i++)); do
23717                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23718                         error "stat f-$i failed"
23719                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23720         done
23721
23722         touch $DIR/$tdir/striped_dir/f0 &&
23723                 error "create under striped dir with unknown hash should fail"
23724
23725         $LCTL set_param fail_loc=0
23726
23727         umount_client $MOUNT || error "umount failed"
23728         mount_client $MOUNT || error "mount failed"
23729
23730         return 0
23731 }
23732 run_test 300i "client handle unknown hash type striped directory"
23733
23734 test_300j() {
23735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23737         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23738                 skip "Need MDS version at least 2.7.55"
23739
23740         local stripe_count
23741         local file
23742
23743         mkdir $DIR/$tdir
23744
23745         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23746         $LCTL set_param fail_loc=0x1702
23747         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23748                 error "set striped dir error"
23749
23750         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23751                 error "create files under striped dir failed"
23752
23753         $LCTL set_param fail_loc=0
23754
23755         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23756
23757         return 0
23758 }
23759 run_test 300j "test large update record"
23760
23761 test_300k() {
23762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23764         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23765                 skip "Need MDS version at least 2.7.55"
23766
23767         # this test needs a huge transaction
23768         local kb
23769         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23770              osd*.$FSNAME-MDT0000.kbytestotal")
23771         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23772
23773         local stripe_count
23774         local file
23775
23776         mkdir $DIR/$tdir
23777
23778         #define OBD_FAIL_LARGE_STRIPE   0x1703
23779         $LCTL set_param fail_loc=0x1703
23780         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23781                 error "set striped dir error"
23782         $LCTL set_param fail_loc=0
23783
23784         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23785                 error "getstripeddir fails"
23786         rm -rf $DIR/$tdir/striped_dir ||
23787                 error "unlink striped dir fails"
23788
23789         return 0
23790 }
23791 run_test 300k "test large striped directory"
23792
23793 test_300l() {
23794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23797                 skip "Need MDS version at least 2.7.55"
23798
23799         local stripe_index
23800
23801         test_mkdir -p $DIR/$tdir/striped_dir
23802         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23803                         error "chown $RUNAS_ID failed"
23804         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23805                 error "set default striped dir failed"
23806
23807         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23808         $LCTL set_param fail_loc=0x80000158
23809         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23810
23811         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23812         [ $stripe_index -eq 1 ] ||
23813                 error "expect 1 get $stripe_index for $dir"
23814 }
23815 run_test 300l "non-root user to create dir under striped dir with stale layout"
23816
23817 test_300m() {
23818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23819         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23820         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23821                 skip "Need MDS version at least 2.7.55"
23822
23823         mkdir -p $DIR/$tdir/striped_dir
23824         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23825                 error "set default stripes dir error"
23826
23827         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23828
23829         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23830         [ $stripe_count -eq 0 ] ||
23831                         error "expect 0 get $stripe_count for a"
23832
23833         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23834                 error "set default stripes dir error"
23835
23836         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23837
23838         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23839         [ $stripe_count -eq 0 ] ||
23840                         error "expect 0 get $stripe_count for b"
23841
23842         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23843                 error "set default stripes dir error"
23844
23845         mkdir $DIR/$tdir/striped_dir/c &&
23846                 error "default stripe_index is invalid, mkdir c should fails"
23847
23848         rm -rf $DIR/$tdir || error "rmdir fails"
23849 }
23850 run_test 300m "setstriped directory on single MDT FS"
23851
23852 cleanup_300n() {
23853         local list=$(comma_list $(mdts_nodes))
23854
23855         trap 0
23856         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23857 }
23858
23859 test_300n() {
23860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23861         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23862         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23863                 skip "Need MDS version at least 2.7.55"
23864         remote_mds_nodsh && skip "remote MDS with nodsh"
23865
23866         local stripe_index
23867         local list=$(comma_list $(mdts_nodes))
23868
23869         trap cleanup_300n RETURN EXIT
23870         mkdir -p $DIR/$tdir
23871         chmod 777 $DIR/$tdir
23872         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23873                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23874                 error "create striped dir succeeds with gid=0"
23875
23876         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23877         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23878                 error "create striped dir fails with gid=-1"
23879
23880         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23881         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23882                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23883                 error "set default striped dir succeeds with gid=0"
23884
23885
23886         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23887         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23888                 error "set default striped dir fails with gid=-1"
23889
23890
23891         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23892         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23893                                         error "create test_dir fails"
23894         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23895                                         error "create test_dir1 fails"
23896         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23897                                         error "create test_dir2 fails"
23898         cleanup_300n
23899 }
23900 run_test 300n "non-root user to create dir under striped dir with default EA"
23901
23902 test_300o() {
23903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23904         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23905         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23906                 skip "Need MDS version at least 2.7.55"
23907
23908         local numfree1
23909         local numfree2
23910
23911         mkdir -p $DIR/$tdir
23912
23913         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23914         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23915         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23916                 skip "not enough free inodes $numfree1 $numfree2"
23917         fi
23918
23919         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23920         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23921         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23922                 skip "not enough free space $numfree1 $numfree2"
23923         fi
23924
23925         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23926                 error "setdirstripe fails"
23927
23928         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23929                 error "create dirs fails"
23930
23931         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23932         ls $DIR/$tdir/striped_dir > /dev/null ||
23933                 error "ls striped dir fails"
23934         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23935                 error "unlink big striped dir fails"
23936 }
23937 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23938
23939 test_300p() {
23940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23942         remote_mds_nodsh && skip "remote MDS with nodsh"
23943
23944         mkdir_on_mdt0 $DIR/$tdir
23945
23946         #define OBD_FAIL_OUT_ENOSPC     0x1704
23947         do_facet mds2 lctl set_param fail_loc=0x80001704
23948         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23949                  && error "create striped directory should fail"
23950
23951         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23952
23953         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23954         true
23955 }
23956 run_test 300p "create striped directory without space"
23957
23958 test_300q() {
23959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23960         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23961
23962         local fd=$(free_fd)
23963         local cmd="exec $fd<$tdir"
23964         cd $DIR
23965         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23966         eval $cmd
23967         cmd="exec $fd<&-"
23968         trap "eval $cmd" EXIT
23969         cd $tdir || error "cd $tdir fails"
23970         rmdir  ../$tdir || error "rmdir $tdir fails"
23971         mkdir local_dir && error "create dir succeeds"
23972         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23973         eval $cmd
23974         return 0
23975 }
23976 run_test 300q "create remote directory under orphan directory"
23977
23978 test_300r() {
23979         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23980                 skip "Need MDS version at least 2.7.55" && return
23981         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23982
23983         mkdir $DIR/$tdir
23984
23985         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23986                 error "set striped dir error"
23987
23988         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23989                 error "getstripeddir fails"
23990
23991         local stripe_count
23992         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23993                       awk '/lmv_stripe_count:/ { print $2 }')
23994
23995         [ $MDSCOUNT -ne $stripe_count ] &&
23996                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23997
23998         rm -rf $DIR/$tdir/striped_dir ||
23999                 error "unlink striped dir fails"
24000 }
24001 run_test 300r "test -1 striped directory"
24002
24003 test_300s_helper() {
24004         local count=$1
24005
24006         local stripe_dir=$DIR/$tdir/striped_dir.$count
24007
24008         $LFS mkdir -c $count $stripe_dir ||
24009                 error "lfs mkdir -c error"
24010
24011         $LFS getdirstripe $stripe_dir ||
24012                 error "lfs getdirstripe fails"
24013
24014         local stripe_count
24015         stripe_count=$($LFS getdirstripe $stripe_dir |
24016                       awk '/lmv_stripe_count:/ { print $2 }')
24017
24018         [ $count -ne $stripe_count ] &&
24019                 error_noexit "bad stripe count $stripe_count expected $count"
24020
24021         local dupe_stripes
24022         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24023                 awk '/0x/ {count[$1] += 1}; END {
24024                         for (idx in count) {
24025                                 if (count[idx]>1) {
24026                                         print "index " idx " count " count[idx]
24027                                 }
24028                         }
24029                 }')
24030
24031         if [[ -n "$dupe_stripes" ]] ; then
24032                 lfs getdirstripe $stripe_dir
24033                 error_noexit "Dupe MDT above: $dupe_stripes "
24034         fi
24035
24036         rm -rf $stripe_dir ||
24037                 error_noexit "unlink $stripe_dir fails"
24038 }
24039
24040 test_300s() {
24041         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24042                 skip "Need MDS version at least 2.7.55" && return
24043         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24044
24045         mkdir $DIR/$tdir
24046         for count in $(seq 2 $MDSCOUNT); do
24047                 test_300s_helper $count
24048         done
24049 }
24050 run_test 300s "test lfs mkdir -c without -i"
24051
24052 test_300t() {
24053         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24054                 skip "need MDS 2.14.55 or later"
24055         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24056
24057         local testdir="$DIR/$tdir/striped_dir"
24058         local dir1=$testdir/dir1
24059         local dir2=$testdir/dir2
24060
24061         mkdir -p $testdir
24062
24063         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24064                 error "failed to set default stripe count for $testdir"
24065
24066         mkdir $dir1
24067         local stripe_count=$($LFS getdirstripe -c $dir1)
24068
24069         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24070
24071         local max_count=$((MDSCOUNT - 1))
24072         local mdts=$(comma_list $(mdts_nodes))
24073
24074         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24075         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24076
24077         mkdir $dir2
24078         stripe_count=$($LFS getdirstripe -c $dir2)
24079
24080         (( $stripe_count == $max_count )) || error "wrong stripe count"
24081 }
24082 run_test 300t "test max_mdt_stripecount"
24083
24084 prepare_remote_file() {
24085         mkdir $DIR/$tdir/src_dir ||
24086                 error "create remote source failed"
24087
24088         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24089                  error "cp to remote source failed"
24090         touch $DIR/$tdir/src_dir/a
24091
24092         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24093                 error "create remote target dir failed"
24094
24095         touch $DIR/$tdir/tgt_dir/b
24096
24097         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24098                 error "rename dir cross MDT failed!"
24099
24100         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24101                 error "src_child still exists after rename"
24102
24103         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24104                 error "missing file(a) after rename"
24105
24106         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24107                 error "diff after rename"
24108 }
24109
24110 test_310a() {
24111         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24113
24114         local remote_file=$DIR/$tdir/tgt_dir/b
24115
24116         mkdir -p $DIR/$tdir
24117
24118         prepare_remote_file || error "prepare remote file failed"
24119
24120         #open-unlink file
24121         $OPENUNLINK $remote_file $remote_file ||
24122                 error "openunlink $remote_file failed"
24123         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24124 }
24125 run_test 310a "open unlink remote file"
24126
24127 test_310b() {
24128         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24130
24131         local remote_file=$DIR/$tdir/tgt_dir/b
24132
24133         mkdir -p $DIR/$tdir
24134
24135         prepare_remote_file || error "prepare remote file failed"
24136
24137         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24138         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24139         $CHECKSTAT -t file $remote_file || error "check file failed"
24140 }
24141 run_test 310b "unlink remote file with multiple links while open"
24142
24143 test_310c() {
24144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24145         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24146
24147         local remote_file=$DIR/$tdir/tgt_dir/b
24148
24149         mkdir -p $DIR/$tdir
24150
24151         prepare_remote_file || error "prepare remote file failed"
24152
24153         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24154         multiop_bg_pause $remote_file O_uc ||
24155                         error "mulitop failed for remote file"
24156         MULTIPID=$!
24157         $MULTIOP $DIR/$tfile Ouc
24158         kill -USR1 $MULTIPID
24159         wait $MULTIPID
24160 }
24161 run_test 310c "open-unlink remote file with multiple links"
24162
24163 #LU-4825
24164 test_311() {
24165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24166         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24167         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24168                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24169         remote_mds_nodsh && skip "remote MDS with nodsh"
24170
24171         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24172         local mdts=$(comma_list $(mdts_nodes))
24173
24174         mkdir -p $DIR/$tdir
24175         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24176         createmany -o $DIR/$tdir/$tfile. 1000
24177
24178         # statfs data is not real time, let's just calculate it
24179         old_iused=$((old_iused + 1000))
24180
24181         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24182                         osp.*OST0000*MDT0000.create_count")
24183         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24184                                 osp.*OST0000*MDT0000.max_create_count")
24185         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24186
24187         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24188         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24189         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24190
24191         unlinkmany $DIR/$tdir/$tfile. 1000
24192
24193         do_nodes $mdts "$LCTL set_param -n \
24194                         osp.*OST0000*.max_create_count=$max_count"
24195         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24196                 do_nodes $mdts "$LCTL set_param -n \
24197                                 osp.*OST0000*.create_count=$count"
24198         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24199                         grep "=0" && error "create_count is zero"
24200
24201         local new_iused
24202         for i in $(seq 120); do
24203                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24204                 # system may be too busy to destroy all objs in time, use
24205                 # a somewhat small value to not fail autotest
24206                 [ $((old_iused - new_iused)) -gt 400 ] && break
24207                 sleep 1
24208         done
24209
24210         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24211         [ $((old_iused - new_iused)) -gt 400 ] ||
24212                 error "objs not destroyed after unlink"
24213 }
24214 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24215
24216 zfs_oid_to_objid()
24217 {
24218         local ost=$1
24219         local objid=$2
24220
24221         local vdevdir=$(dirname $(facet_vdevice $ost))
24222         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24223         local zfs_zapid=$(do_facet $ost $cmd |
24224                           grep -w "/O/0/d$((objid%32))" -C 5 |
24225                           awk '/Object/{getline; print $1}')
24226         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24227                           awk "/$objid = /"'{printf $3}')
24228
24229         echo $zfs_objid
24230 }
24231
24232 zfs_object_blksz() {
24233         local ost=$1
24234         local objid=$2
24235
24236         local vdevdir=$(dirname $(facet_vdevice $ost))
24237         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24238         local blksz=$(do_facet $ost $cmd $objid |
24239                       awk '/dblk/{getline; printf $4}')
24240
24241         case "${blksz: -1}" in
24242                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24243                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24244                 *) ;;
24245         esac
24246
24247         echo $blksz
24248 }
24249
24250 test_312() { # LU-4856
24251         remote_ost_nodsh && skip "remote OST with nodsh"
24252         [ "$ost1_FSTYPE" = "zfs" ] ||
24253                 skip_env "the test only applies to zfs"
24254
24255         local max_blksz=$(do_facet ost1 \
24256                           $ZFS get -p recordsize $(facet_device ost1) |
24257                           awk '!/VALUE/{print $3}')
24258
24259         # to make life a little bit easier
24260         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24261         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24262
24263         local tf=$DIR/$tdir/$tfile
24264         touch $tf
24265         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24266
24267         # Get ZFS object id
24268         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24269         # block size change by sequential overwrite
24270         local bs
24271
24272         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24273                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24274
24275                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24276                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24277         done
24278         rm -f $tf
24279
24280         # block size change by sequential append write
24281         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24282         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24283         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24284         local count
24285
24286         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24287                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24288                         oflag=sync conv=notrunc
24289
24290                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24291                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24292                         error "blksz error, actual $blksz, " \
24293                                 "expected: 2 * $count * $PAGE_SIZE"
24294         done
24295         rm -f $tf
24296
24297         # random write
24298         touch $tf
24299         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24300         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24301
24302         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24303         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24304         [ $blksz -eq $PAGE_SIZE ] ||
24305                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24306
24307         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24308         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24309         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24310
24311         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24312         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24313         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24314 }
24315 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24316
24317 test_313() {
24318         remote_ost_nodsh && skip "remote OST with nodsh"
24319
24320         local file=$DIR/$tfile
24321
24322         rm -f $file
24323         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24324
24325         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24326         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24327         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24328                 error "write should failed"
24329         do_facet ost1 "$LCTL set_param fail_loc=0"
24330         rm -f $file
24331 }
24332 run_test 313 "io should fail after last_rcvd update fail"
24333
24334 test_314() {
24335         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24336
24337         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24338         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24339         rm -f $DIR/$tfile
24340         wait_delete_completed
24341         do_facet ost1 "$LCTL set_param fail_loc=0"
24342 }
24343 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24344
24345 test_315() { # LU-618
24346         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24347
24348         local file=$DIR/$tfile
24349         rm -f $file
24350
24351         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24352                 error "multiop file write failed"
24353         $MULTIOP $file oO_RDONLY:r4063232_c &
24354         PID=$!
24355
24356         sleep 2
24357
24358         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24359         kill -USR1 $PID
24360
24361         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24362         rm -f $file
24363 }
24364 run_test 315 "read should be accounted"
24365
24366 test_316() {
24367         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24368         large_xattr_enabled || skip "ea_inode feature disabled"
24369
24370         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24371         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24372         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24373         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24374
24375         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24376 }
24377 run_test 316 "lfs migrate of file with large_xattr enabled"
24378
24379 test_317() {
24380         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24381                 skip "Need MDS version at least 2.11.53"
24382         if [ "$ost1_FSTYPE" == "zfs" ]; then
24383                 skip "LU-10370: no implementation for ZFS"
24384         fi
24385
24386         local trunc_sz
24387         local grant_blk_size
24388
24389         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24390                         awk '/grant_block_size:/ { print $2; exit; }')
24391         #
24392         # Create File of size 5M. Truncate it to below size's and verify
24393         # blocks count.
24394         #
24395         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24396                 error "Create file $DIR/$tfile failed"
24397         stack_trap "rm -f $DIR/$tfile" EXIT
24398
24399         for trunc_sz in 2097152 4097 4000 509 0; do
24400                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24401                         error "truncate $tfile to $trunc_sz failed"
24402                 local sz=$(stat --format=%s $DIR/$tfile)
24403                 local blk=$(stat --format=%b $DIR/$tfile)
24404                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24405                                      grant_blk_size) * 8))
24406
24407                 if [[ $blk -ne $trunc_blk ]]; then
24408                         $(which stat) $DIR/$tfile
24409                         error "Expected Block $trunc_blk got $blk for $tfile"
24410                 fi
24411
24412                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24413                         error "Expected Size $trunc_sz got $sz for $tfile"
24414         done
24415
24416         #
24417         # sparse file test
24418         # Create file with a hole and write actual 65536 bytes which aligned
24419         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24420         #
24421         local bs=65536
24422         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24423                 error "Create file : $DIR/$tfile"
24424
24425         #
24426         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24427         # blocks. The block count must drop to 8.
24428         #
24429         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24430                 ((bs - grant_blk_size) + 1)))
24431         $TRUNCATE $DIR/$tfile $trunc_sz ||
24432                 error "truncate $tfile to $trunc_sz failed"
24433
24434         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24435         sz=$(stat --format=%s $DIR/$tfile)
24436         blk=$(stat --format=%b $DIR/$tfile)
24437
24438         if [[ $blk -ne $trunc_bsz ]]; then
24439                 $(which stat) $DIR/$tfile
24440                 error "Expected Block $trunc_bsz got $blk for $tfile"
24441         fi
24442
24443         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24444                 error "Expected Size $trunc_sz got $sz for $tfile"
24445 }
24446 run_test 317 "Verify blocks get correctly update after truncate"
24447
24448 test_318() {
24449         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24450         local old_max_active=$($LCTL get_param -n \
24451                             ${llite_name}.max_read_ahead_async_active \
24452                             2>/dev/null)
24453
24454         $LCTL set_param llite.*.max_read_ahead_async_active=256
24455         local max_active=$($LCTL get_param -n \
24456                            ${llite_name}.max_read_ahead_async_active \
24457                            2>/dev/null)
24458         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24459
24460         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24461                 error "set max_read_ahead_async_active should succeed"
24462
24463         $LCTL set_param llite.*.max_read_ahead_async_active=512
24464         max_active=$($LCTL get_param -n \
24465                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24466         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24467
24468         # restore @max_active
24469         [ $old_max_active -ne 0 ] && $LCTL set_param \
24470                 llite.*.max_read_ahead_async_active=$old_max_active
24471
24472         local old_threshold=$($LCTL get_param -n \
24473                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24474         local max_per_file_mb=$($LCTL get_param -n \
24475                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24476
24477         local invalid=$(($max_per_file_mb + 1))
24478         $LCTL set_param \
24479                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24480                         && error "set $invalid should fail"
24481
24482         local valid=$(($invalid - 1))
24483         $LCTL set_param \
24484                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24485                         error "set $valid should succeed"
24486         local threshold=$($LCTL get_param -n \
24487                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24488         [ $threshold -eq $valid ] || error \
24489                 "expect threshold $valid got $threshold"
24490         $LCTL set_param \
24491                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24492 }
24493 run_test 318 "Verify async readahead tunables"
24494
24495 test_319() {
24496         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24497
24498         local before=$(date +%s)
24499         local evict
24500         local mdir=$DIR/$tdir
24501         local file=$mdir/xxx
24502
24503         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24504         touch $file
24505
24506 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24507         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24508         $LFS migrate -m1 $mdir &
24509
24510         sleep 1
24511         dd if=$file of=/dev/null
24512         wait
24513         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24514           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24515
24516         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24517 }
24518 run_test 319 "lost lease lock on migrate error"
24519
24520 test_398a() { # LU-4198
24521         local ost1_imp=$(get_osc_import_name client ost1)
24522         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24523                          cut -d'.' -f2)
24524
24525         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24526         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24527
24528         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24529         # request a new lock on client
24530         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24531
24532         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24533         #local lock_count=$($LCTL get_param -n \
24534         #                  ldlm.namespaces.$imp_name.lru_size)
24535         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24536
24537         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24538
24539         # no lock cached, should use lockless DIO and not enqueue new lock
24540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24541                 conv=notrunc ||
24542                 error "dio write failed"
24543         lock_count=$($LCTL get_param -n \
24544                      ldlm.namespaces.$imp_name.lru_size)
24545         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24546
24547         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24548
24549         # no lock cached, should use locked DIO append
24550         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24551                 conv=notrunc || error "DIO append failed"
24552         lock_count=$($LCTL get_param -n \
24553                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24554         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24555 }
24556 run_test 398a "direct IO should cancel lock otherwise lockless"
24557
24558 test_398b() { # LU-4198
24559         which fio || skip_env "no fio installed"
24560         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24561
24562         local size=48
24563         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24564
24565         local njobs=4
24566         # Single page, multiple pages, stripe size, 4*stripe size
24567         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24568                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24569                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24570                         --numjobs=$njobs --fallocate=none \
24571                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24572                         --filename=$DIR/$tfile &
24573                 bg_pid=$!
24574
24575                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24576                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24577                         --numjobs=$njobs --fallocate=none \
24578                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24579                         --filename=$DIR/$tfile || true
24580                 wait $bg_pid
24581         done
24582
24583         evict=$(do_facet client $LCTL get_param \
24584                 osc.$FSNAME-OST*-osc-*/state |
24585             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24586
24587         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24588                 (do_facet client $LCTL get_param \
24589                         osc.$FSNAME-OST*-osc-*/state;
24590                     error "eviction happened: $evict before:$before")
24591
24592         rm -f $DIR/$tfile
24593 }
24594 run_test 398b "DIO and buffer IO race"
24595
24596 test_398c() { # LU-4198
24597         local ost1_imp=$(get_osc_import_name client ost1)
24598         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24599                          cut -d'.' -f2)
24600
24601         which fio || skip_env "no fio installed"
24602
24603         saved_debug=$($LCTL get_param -n debug)
24604         $LCTL set_param debug=0
24605
24606         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24607         ((size /= 1024)) # by megabytes
24608         ((size /= 2)) # write half of the OST at most
24609         [ $size -gt 40 ] && size=40 #reduce test time anyway
24610
24611         $LFS setstripe -c 1 $DIR/$tfile
24612
24613         # it seems like ldiskfs reserves more space than necessary if the
24614         # writing blocks are not mapped, so it extends the file firstly
24615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24616         cancel_lru_locks osc
24617
24618         # clear and verify rpc_stats later
24619         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24620
24621         local njobs=4
24622         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24623         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24624                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24625                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24626                 --filename=$DIR/$tfile
24627         [ $? -eq 0 ] || error "fio write error"
24628
24629         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24630                 error "Locks were requested while doing AIO"
24631
24632         # get the percentage of 1-page I/O
24633         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24634                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24635                 awk '{print $7}')
24636         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24637
24638         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24639         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24640                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24641                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24642                 --filename=$DIR/$tfile
24643         [ $? -eq 0 ] || error "fio mixed read write error"
24644
24645         echo "AIO with large block size ${size}M"
24646         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24647                 --numjobs=1 --fallocate=none --ioengine=libaio \
24648                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24649                 --filename=$DIR/$tfile
24650         [ $? -eq 0 ] || error "fio large block size failed"
24651
24652         rm -f $DIR/$tfile
24653         $LCTL set_param debug="$saved_debug"
24654 }
24655 run_test 398c "run fio to test AIO"
24656
24657 test_398d() { #  LU-13846
24658         which aiocp || skip_env "no aiocp installed"
24659         local aio_file=$DIR/$tfile.aio
24660
24661         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24662
24663         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24664         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24665         stack_trap "rm -f $DIR/$tfile $aio_file"
24666
24667         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24668
24669         # make sure we don't crash and fail properly
24670         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24671                 error "aio not aligned with PAGE SIZE should fail"
24672
24673         rm -f $DIR/$tfile $aio_file
24674 }
24675 run_test 398d "run aiocp to verify block size > stripe size"
24676
24677 test_398e() {
24678         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24679         touch $DIR/$tfile.new
24680         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24681 }
24682 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24683
24684 test_398f() { #  LU-14687
24685         which aiocp || skip_env "no aiocp installed"
24686         local aio_file=$DIR/$tfile.aio
24687
24688         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24689
24690         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24691         stack_trap "rm -f $DIR/$tfile $aio_file"
24692
24693         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24694         $LCTL set_param fail_loc=0x1418
24695         # make sure we don't crash and fail properly
24696         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24697                 error "aio with page allocation failure succeeded"
24698         $LCTL set_param fail_loc=0
24699         diff $DIR/$tfile $aio_file
24700         [[ $? != 0 ]] || error "no diff after failed aiocp"
24701 }
24702 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24703
24704 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24705 # stripe and i/o size must be > stripe size
24706 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24707 # single RPC in flight.  This test shows async DIO submission is working by
24708 # showing multiple RPCs in flight.
24709 test_398g() { #  LU-13798
24710         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24711
24712         # We need to do some i/o first to acquire enough grant to put our RPCs
24713         # in flight; otherwise a new connection may not have enough grant
24714         # available
24715         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24716                 error "parallel dio failed"
24717         stack_trap "rm -f $DIR/$tfile"
24718
24719         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24720         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24721         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24722         stack_trap "$LCTL set_param -n $pages_per_rpc"
24723
24724         # Recreate file so it's empty
24725         rm -f $DIR/$tfile
24726         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24727         #Pause rpc completion to guarantee we see multiple rpcs in flight
24728         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24729         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24730         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24731
24732         # Clear rpc stats
24733         $LCTL set_param osc.*.rpc_stats=c
24734
24735         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24736                 error "parallel dio failed"
24737         stack_trap "rm -f $DIR/$tfile"
24738
24739         $LCTL get_param osc.*-OST0000-*.rpc_stats
24740         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24741                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24742                 grep "8:" | awk '{print $8}')
24743         # We look at the "8 rpcs in flight" field, and verify A) it is present
24744         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24745         # as expected for an 8M DIO to a file with 1M stripes.
24746         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24747
24748         # Verify turning off parallel dio works as expected
24749         # Clear rpc stats
24750         $LCTL set_param osc.*.rpc_stats=c
24751         $LCTL set_param llite.*.parallel_dio=0
24752         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24753
24754         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24755                 error "dio with parallel dio disabled failed"
24756
24757         # Ideally, we would see only one RPC in flight here, but there is an
24758         # unavoidable race between i/o completion and RPC in flight counting,
24759         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24760         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24761         # So instead we just verify it's always < 8.
24762         $LCTL get_param osc.*-OST0000-*.rpc_stats
24763         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24764                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24765                 grep '^$' -B1 | grep . | awk '{print $1}')
24766         [ $ret != "8:" ] ||
24767                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24768 }
24769 run_test 398g "verify parallel dio async RPC submission"
24770
24771 test_398h() { #  LU-13798
24772         local dio_file=$DIR/$tfile.dio
24773
24774         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24775
24776         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24777         stack_trap "rm -f $DIR/$tfile $dio_file"
24778
24779         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24780                 error "parallel dio failed"
24781         diff $DIR/$tfile $dio_file
24782         [[ $? == 0 ]] || error "file diff after aiocp"
24783 }
24784 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24785
24786 test_398i() { #  LU-13798
24787         local dio_file=$DIR/$tfile.dio
24788
24789         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24790
24791         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24792         stack_trap "rm -f $DIR/$tfile $dio_file"
24793
24794         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24795         $LCTL set_param fail_loc=0x1418
24796         # make sure we don't crash and fail properly
24797         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24798                 error "parallel dio page allocation failure succeeded"
24799         diff $DIR/$tfile $dio_file
24800         [[ $? != 0 ]] || error "no diff after failed aiocp"
24801 }
24802 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24803
24804 test_398j() { #  LU-13798
24805         # Stripe size > RPC size but less than i/o size tests split across
24806         # stripes and RPCs for individual i/o op
24807         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24808
24809         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24810         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24811         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24812         stack_trap "$LCTL set_param -n $pages_per_rpc"
24813
24814         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24815                 error "parallel dio write failed"
24816         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24817
24818         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24819                 error "parallel dio read failed"
24820         diff $DIR/$tfile $DIR/$tfile.2
24821         [[ $? == 0 ]] || error "file diff after parallel dio read"
24822 }
24823 run_test 398j "test parallel dio where stripe size > rpc_size"
24824
24825 test_398k() { #  LU-13798
24826         wait_delete_completed
24827         wait_mds_ost_sync
24828
24829         # 4 stripe file; we will cause out of space on OST0
24830         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24831
24832         # Fill OST0 (if it's not too large)
24833         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24834                    head -n1)
24835         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24836                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24837         fi
24838         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24839         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24840                 error "dd should fill OST0"
24841         stack_trap "rm -f $DIR/$tfile.1"
24842
24843         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24844         err=$?
24845
24846         ls -la $DIR/$tfile
24847         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24848                 error "file is not 0 bytes in size"
24849
24850         # dd above should not succeed, but don't error until here so we can
24851         # get debug info above
24852         [[ $err != 0 ]] ||
24853                 error "parallel dio write with enospc succeeded"
24854         stack_trap "rm -f $DIR/$tfile"
24855 }
24856 run_test 398k "test enospc on first stripe"
24857
24858 test_398l() { #  LU-13798
24859         wait_delete_completed
24860         wait_mds_ost_sync
24861
24862         # 4 stripe file; we will cause out of space on OST0
24863         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24864         # happens on the second i/o chunk we issue
24865         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24866
24867         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24868         stack_trap "rm -f $DIR/$tfile"
24869
24870         # Fill OST0 (if it's not too large)
24871         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24872                    head -n1)
24873         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24874                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24875         fi
24876         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24877         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24878                 error "dd should fill OST0"
24879         stack_trap "rm -f $DIR/$tfile.1"
24880
24881         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24882         err=$?
24883         stack_trap "rm -f $DIR/$tfile.2"
24884
24885         # Check that short write completed as expected
24886         ls -la $DIR/$tfile.2
24887         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24888                 error "file is not 1M in size"
24889
24890         # dd above should not succeed, but don't error until here so we can
24891         # get debug info above
24892         [[ $err != 0 ]] ||
24893                 error "parallel dio write with enospc succeeded"
24894
24895         # Truncate source file to same length as output file and diff them
24896         $TRUNCATE $DIR/$tfile 1048576
24897         diff $DIR/$tfile $DIR/$tfile.2
24898         [[ $? == 0 ]] || error "data incorrect after short write"
24899 }
24900 run_test 398l "test enospc on intermediate stripe/RPC"
24901
24902 test_398m() { #  LU-13798
24903         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24904
24905         # Set up failure on OST0, the first stripe:
24906         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24907         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24908         # So this fail_val specifies OST0
24909         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24910         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24911
24912         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24913                 error "parallel dio write with failure on first stripe succeeded"
24914         stack_trap "rm -f $DIR/$tfile"
24915         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24916
24917         # Place data in file for read
24918         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24919                 error "parallel dio write failed"
24920
24921         # Fail read on OST0, first stripe
24922         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24923         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24924         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24925                 error "parallel dio read with error on first stripe succeeded"
24926         rm -f $DIR/$tfile.2
24927         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24928
24929         # Switch to testing on OST1, second stripe
24930         # Clear file contents, maintain striping
24931         echo > $DIR/$tfile
24932         # Set up failure on OST1, second stripe:
24933         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24934         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24935
24936         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24937                 error "parallel dio write with failure on first stripe succeeded"
24938         stack_trap "rm -f $DIR/$tfile"
24939         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24940
24941         # Place data in file for read
24942         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24943                 error "parallel dio write failed"
24944
24945         # Fail read on OST1, second stripe
24946         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24947         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24948         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24949                 error "parallel dio read with error on first stripe succeeded"
24950         rm -f $DIR/$tfile.2
24951         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24952 }
24953 run_test 398m "test RPC failures with parallel dio"
24954
24955 # Parallel submission of DIO should not cause problems for append, but it's
24956 # important to verify.
24957 test_398n() { #  LU-13798
24958         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24959
24960         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24961                 error "dd to create source file failed"
24962         stack_trap "rm -f $DIR/$tfile"
24963
24964         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24965                 error "parallel dio write with failure on second stripe succeeded"
24966         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24967         diff $DIR/$tfile $DIR/$tfile.1
24968         [[ $? == 0 ]] || error "data incorrect after append"
24969
24970 }
24971 run_test 398n "test append with parallel DIO"
24972
24973 test_fake_rw() {
24974         local read_write=$1
24975         if [ "$read_write" = "write" ]; then
24976                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24977         elif [ "$read_write" = "read" ]; then
24978                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24979         else
24980                 error "argument error"
24981         fi
24982
24983         # turn off debug for performance testing
24984         local saved_debug=$($LCTL get_param -n debug)
24985         $LCTL set_param debug=0
24986
24987         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24988
24989         # get ost1 size - $FSNAME-OST0000
24990         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24991         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24992         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24993
24994         if [ "$read_write" = "read" ]; then
24995                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24996         fi
24997
24998         local start_time=$(date +%s.%N)
24999         $dd_cmd bs=1M count=$blocks oflag=sync ||
25000                 error "real dd $read_write error"
25001         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25002
25003         if [ "$read_write" = "write" ]; then
25004                 rm -f $DIR/$tfile
25005         fi
25006
25007         # define OBD_FAIL_OST_FAKE_RW           0x238
25008         do_facet ost1 $LCTL set_param fail_loc=0x238
25009
25010         local start_time=$(date +%s.%N)
25011         $dd_cmd bs=1M count=$blocks oflag=sync ||
25012                 error "fake dd $read_write error"
25013         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25014
25015         if [ "$read_write" = "write" ]; then
25016                 # verify file size
25017                 cancel_lru_locks osc
25018                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25019                         error "$tfile size not $blocks MB"
25020         fi
25021         do_facet ost1 $LCTL set_param fail_loc=0
25022
25023         echo "fake $read_write $duration_fake vs. normal $read_write" \
25024                 "$duration in seconds"
25025         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25026                 error_not_in_vm "fake write is slower"
25027
25028         $LCTL set_param -n debug="$saved_debug"
25029         rm -f $DIR/$tfile
25030 }
25031 test_399a() { # LU-7655 for OST fake write
25032         remote_ost_nodsh && skip "remote OST with nodsh"
25033
25034         test_fake_rw write
25035 }
25036 run_test 399a "fake write should not be slower than normal write"
25037
25038 test_399b() { # LU-8726 for OST fake read
25039         remote_ost_nodsh && skip "remote OST with nodsh"
25040         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25041                 skip_env "ldiskfs only test"
25042         fi
25043
25044         test_fake_rw read
25045 }
25046 run_test 399b "fake read should not be slower than normal read"
25047
25048 test_400a() { # LU-1606, was conf-sanity test_74
25049         if ! which $CC > /dev/null 2>&1; then
25050                 skip_env "$CC is not installed"
25051         fi
25052
25053         local extra_flags=''
25054         local out=$TMP/$tfile
25055         local prefix=/usr/include/lustre
25056         local prog
25057
25058         # Oleg removes c files in his test rig so test if any c files exist
25059         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25060                 skip_env "Needed c test files are missing"
25061
25062         if ! [[ -d $prefix ]]; then
25063                 # Assume we're running in tree and fixup the include path.
25064                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25065                 extra_flags+=" -L$LUSTRE/utils/.lib"
25066         fi
25067
25068         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25069                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25070                         error "client api broken"
25071         done
25072         rm -f $out
25073 }
25074 run_test 400a "Lustre client api program can compile and link"
25075
25076 test_400b() { # LU-1606, LU-5011
25077         local header
25078         local out=$TMP/$tfile
25079         local prefix=/usr/include/linux/lustre
25080
25081         # We use a hard coded prefix so that this test will not fail
25082         # when run in tree. There are headers in lustre/include/lustre/
25083         # that are not packaged (like lustre_idl.h) and have more
25084         # complicated include dependencies (like config.h and lnet/types.h).
25085         # Since this test about correct packaging we just skip them when
25086         # they don't exist (see below) rather than try to fixup cppflags.
25087
25088         if ! which $CC > /dev/null 2>&1; then
25089                 skip_env "$CC is not installed"
25090         fi
25091
25092         for header in $prefix/*.h; do
25093                 if ! [[ -f "$header" ]]; then
25094                         continue
25095                 fi
25096
25097                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25098                         continue # lustre_ioctl.h is internal header
25099                 fi
25100
25101                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25102                         error "cannot compile '$header'"
25103         done
25104         rm -f $out
25105 }
25106 run_test 400b "packaged headers can be compiled"
25107
25108 test_401a() { #LU-7437
25109         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25110         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25111
25112         #count the number of parameters by "list_param -R"
25113         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25114         #count the number of parameters by listing proc files
25115         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25116         echo "proc_dirs='$proc_dirs'"
25117         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25118         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25119                       sort -u | wc -l)
25120
25121         [ $params -eq $procs ] ||
25122                 error "found $params parameters vs. $procs proc files"
25123
25124         # test the list_param -D option only returns directories
25125         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25126         #count the number of parameters by listing proc directories
25127         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25128                 sort -u | wc -l)
25129
25130         [ $params -eq $procs ] ||
25131                 error "found $params parameters vs. $procs proc files"
25132 }
25133 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25134
25135 test_401b() {
25136         # jobid_var may not allow arbitrary values, so use jobid_name
25137         # if available
25138         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25139                 local testname=jobid_name tmp='testing%p'
25140         else
25141                 local testname=jobid_var tmp=testing
25142         fi
25143
25144         local save=$($LCTL get_param -n $testname)
25145
25146         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25147                 error "no error returned when setting bad parameters"
25148
25149         local jobid_new=$($LCTL get_param -n foe $testname baz)
25150         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25151
25152         $LCTL set_param -n fog=bam $testname=$save bat=fog
25153         local jobid_old=$($LCTL get_param -n foe $testname bag)
25154         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25155 }
25156 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25157
25158 test_401c() {
25159         # jobid_var may not allow arbitrary values, so use jobid_name
25160         # if available
25161         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25162                 local testname=jobid_name
25163         else
25164                 local testname=jobid_var
25165         fi
25166
25167         local jobid_var_old=$($LCTL get_param -n $testname)
25168         local jobid_var_new
25169
25170         $LCTL set_param $testname= &&
25171                 error "no error returned for 'set_param a='"
25172
25173         jobid_var_new=$($LCTL get_param -n $testname)
25174         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25175                 error "$testname was changed by setting without value"
25176
25177         $LCTL set_param $testname &&
25178                 error "no error returned for 'set_param a'"
25179
25180         jobid_var_new=$($LCTL get_param -n $testname)
25181         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25182                 error "$testname was changed by setting without value"
25183 }
25184 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25185
25186 test_401d() {
25187         # jobid_var may not allow arbitrary values, so use jobid_name
25188         # if available
25189         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25190                 local testname=jobid_name new_value='foo=bar%p'
25191         else
25192                 local testname=jobid_var new_valuie=foo=bar
25193         fi
25194
25195         local jobid_var_old=$($LCTL get_param -n $testname)
25196         local jobid_var_new
25197
25198         $LCTL set_param $testname=$new_value ||
25199                 error "'set_param a=b' did not accept a value containing '='"
25200
25201         jobid_var_new=$($LCTL get_param -n $testname)
25202         [[ "$jobid_var_new" == "$new_value" ]] ||
25203                 error "'set_param a=b' failed on a value containing '='"
25204
25205         # Reset the $testname to test the other format
25206         $LCTL set_param $testname=$jobid_var_old
25207         jobid_var_new=$($LCTL get_param -n $testname)
25208         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25209                 error "failed to reset $testname"
25210
25211         $LCTL set_param $testname $new_value ||
25212                 error "'set_param a b' did not accept a value containing '='"
25213
25214         jobid_var_new=$($LCTL get_param -n $testname)
25215         [[ "$jobid_var_new" == "$new_value" ]] ||
25216                 error "'set_param a b' failed on a value containing '='"
25217
25218         $LCTL set_param $testname $jobid_var_old
25219         jobid_var_new=$($LCTL get_param -n $testname)
25220         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25221                 error "failed to reset $testname"
25222 }
25223 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25224
25225 test_401e() { # LU-14779
25226         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25227                 error "lctl list_param MGC* failed"
25228         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25229         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25230                 error "lctl get_param lru_size failed"
25231 }
25232 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25233
25234 test_402() {
25235         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25236         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25237                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25238         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25239                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25240                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25241         remote_mds_nodsh && skip "remote MDS with nodsh"
25242
25243         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25244 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25245         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25246         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25247                 echo "Touch failed - OK"
25248 }
25249 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25250
25251 test_403() {
25252         local file1=$DIR/$tfile.1
25253         local file2=$DIR/$tfile.2
25254         local tfile=$TMP/$tfile
25255
25256         rm -f $file1 $file2 $tfile
25257
25258         touch $file1
25259         ln $file1 $file2
25260
25261         # 30 sec OBD_TIMEOUT in ll_getattr()
25262         # right before populating st_nlink
25263         $LCTL set_param fail_loc=0x80001409
25264         stat -c %h $file1 > $tfile &
25265
25266         # create an alias, drop all locks and reclaim the dentry
25267         < $file2
25268         cancel_lru_locks mdc
25269         cancel_lru_locks osc
25270         sysctl -w vm.drop_caches=2
25271
25272         wait
25273
25274         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25275
25276         rm -f $tfile $file1 $file2
25277 }
25278 run_test 403 "i_nlink should not drop to zero due to aliasing"
25279
25280 test_404() { # LU-6601
25281         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25282                 skip "Need server version newer than 2.8.52"
25283         remote_mds_nodsh && skip "remote MDS with nodsh"
25284
25285         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25286                 awk '/osp .*-osc-MDT/ { print $4}')
25287
25288         local osp
25289         for osp in $mosps; do
25290                 echo "Deactivate: " $osp
25291                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25292                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25293                         awk -vp=$osp '$4 == p { print $2 }')
25294                 [ $stat = IN ] || {
25295                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25296                         error "deactivate error"
25297                 }
25298                 echo "Activate: " $osp
25299                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25300                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25301                         awk -vp=$osp '$4 == p { print $2 }')
25302                 [ $stat = UP ] || {
25303                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25304                         error "activate error"
25305                 }
25306         done
25307 }
25308 run_test 404 "validate manual {de}activated works properly for OSPs"
25309
25310 test_405() {
25311         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25312         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25313                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25314                         skip "Layout swap lock is not supported"
25315
25316         check_swap_layouts_support
25317         check_swap_layout_no_dom $DIR
25318
25319         test_mkdir $DIR/$tdir
25320         swap_lock_test -d $DIR/$tdir ||
25321                 error "One layout swap locked test failed"
25322 }
25323 run_test 405 "Various layout swap lock tests"
25324
25325 test_406() {
25326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25327         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25330         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25331                 skip "Need MDS version at least 2.8.50"
25332
25333         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25334         local test_pool=$TESTNAME
25335
25336         pool_add $test_pool || error "pool_add failed"
25337         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25338                 error "pool_add_targets failed"
25339
25340         save_layout_restore_at_exit $MOUNT
25341
25342         # parent set default stripe count only, child will stripe from both
25343         # parent and fs default
25344         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25345                 error "setstripe $MOUNT failed"
25346         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25347         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25348         for i in $(seq 10); do
25349                 local f=$DIR/$tdir/$tfile.$i
25350                 touch $f || error "touch failed"
25351                 local count=$($LFS getstripe -c $f)
25352                 [ $count -eq $OSTCOUNT ] ||
25353                         error "$f stripe count $count != $OSTCOUNT"
25354                 local offset=$($LFS getstripe -i $f)
25355                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25356                 local size=$($LFS getstripe -S $f)
25357                 [ $size -eq $((def_stripe_size * 2)) ] ||
25358                         error "$f stripe size $size != $((def_stripe_size * 2))"
25359                 local pool=$($LFS getstripe -p $f)
25360                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25361         done
25362
25363         # change fs default striping, delete parent default striping, now child
25364         # will stripe from new fs default striping only
25365         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25366                 error "change $MOUNT default stripe failed"
25367         $LFS setstripe -c 0 $DIR/$tdir ||
25368                 error "delete $tdir default stripe failed"
25369         for i in $(seq 11 20); do
25370                 local f=$DIR/$tdir/$tfile.$i
25371                 touch $f || error "touch $f failed"
25372                 local count=$($LFS getstripe -c $f)
25373                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25374                 local offset=$($LFS getstripe -i $f)
25375                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25376                 local size=$($LFS getstripe -S $f)
25377                 [ $size -eq $def_stripe_size ] ||
25378                         error "$f stripe size $size != $def_stripe_size"
25379                 local pool=$($LFS getstripe -p $f)
25380                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25381         done
25382
25383         unlinkmany $DIR/$tdir/$tfile. 1 20
25384
25385         local f=$DIR/$tdir/$tfile
25386         pool_remove_all_targets $test_pool $f
25387         pool_remove $test_pool $f
25388 }
25389 run_test 406 "DNE support fs default striping"
25390
25391 test_407() {
25392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25393         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25394                 skip "Need MDS version at least 2.8.55"
25395         remote_mds_nodsh && skip "remote MDS with nodsh"
25396
25397         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25398                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25399         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25400                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25401         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25402
25403         #define OBD_FAIL_DT_TXN_STOP    0x2019
25404         for idx in $(seq $MDSCOUNT); do
25405                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25406         done
25407         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25408         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25409                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25410         true
25411 }
25412 run_test 407 "transaction fail should cause operation fail"
25413
25414 test_408() {
25415         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25416
25417         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25418         lctl set_param fail_loc=0x8000040a
25419         # let ll_prepare_partial_page() fail
25420         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25421
25422         rm -f $DIR/$tfile
25423
25424         # create at least 100 unused inodes so that
25425         # shrink_icache_memory(0) should not return 0
25426         touch $DIR/$tfile-{0..100}
25427         rm -f $DIR/$tfile-{0..100}
25428         sync
25429
25430         echo 2 > /proc/sys/vm/drop_caches
25431 }
25432 run_test 408 "drop_caches should not hang due to page leaks"
25433
25434 test_409()
25435 {
25436         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25437
25438         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25439         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25440         touch $DIR/$tdir/guard || error "(2) Fail to create"
25441
25442         local PREFIX=$(str_repeat 'A' 128)
25443         echo "Create 1K hard links start at $(date)"
25444         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25445                 error "(3) Fail to hard link"
25446
25447         echo "Links count should be right although linkEA overflow"
25448         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25449         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25450         [ $linkcount -eq 1001 ] ||
25451                 error "(5) Unexpected hard links count: $linkcount"
25452
25453         echo "List all links start at $(date)"
25454         ls -l $DIR/$tdir/foo > /dev/null ||
25455                 error "(6) Fail to list $DIR/$tdir/foo"
25456
25457         echo "Unlink hard links start at $(date)"
25458         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25459                 error "(7) Fail to unlink"
25460         echo "Unlink hard links finished at $(date)"
25461 }
25462 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25463
25464 test_410()
25465 {
25466         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25467                 skip "Need client version at least 2.9.59"
25468         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25469                 skip "Need MODULES build"
25470
25471         # Create a file, and stat it from the kernel
25472         local testfile=$DIR/$tfile
25473         touch $testfile
25474
25475         local run_id=$RANDOM
25476         local my_ino=$(stat --format "%i" $testfile)
25477
25478         # Try to insert the module. This will always fail as the
25479         # module is designed to not be inserted.
25480         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25481             &> /dev/null
25482
25483         # Anything but success is a test failure
25484         dmesg | grep -q \
25485             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25486             error "no inode match"
25487 }
25488 run_test 410 "Test inode number returned from kernel thread"
25489
25490 cleanup_test411_cgroup() {
25491         trap 0
25492         rmdir "$1"
25493 }
25494
25495 test_411() {
25496         local cg_basedir=/sys/fs/cgroup/memory
25497         # LU-9966
25498         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25499                 skip "no setup for cgroup"
25500
25501         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25502                 error "test file creation failed"
25503         cancel_lru_locks osc
25504
25505         # Create a very small memory cgroup to force a slab allocation error
25506         local cgdir=$cg_basedir/osc_slab_alloc
25507         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25508         trap "cleanup_test411_cgroup $cgdir" EXIT
25509         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25510         echo 1M > $cgdir/memory.limit_in_bytes
25511
25512         # Should not LBUG, just be killed by oom-killer
25513         # dd will return 0 even allocation failure in some environment.
25514         # So don't check return value
25515         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25516         cleanup_test411_cgroup $cgdir
25517
25518         return 0
25519 }
25520 run_test 411 "Slab allocation error with cgroup does not LBUG"
25521
25522 test_412() {
25523         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25524         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25525                 skip "Need server version at least 2.10.55"
25526
25527         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25528                 error "mkdir failed"
25529         $LFS getdirstripe $DIR/$tdir
25530         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25531         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25532                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25533         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25534         [ $stripe_count -eq 2 ] ||
25535                 error "expect 2 get $stripe_count"
25536
25537         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25538
25539         local index
25540         local index2
25541
25542         # subdirs should be on the same MDT as parent
25543         for i in $(seq 0 $((MDSCOUNT - 1))); do
25544                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25545                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25546                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25547                 (( index == i )) || error "mdt$i/sub on MDT$index"
25548         done
25549
25550         # stripe offset -1, ditto
25551         for i in {1..10}; do
25552                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25553                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25554                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25555                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25556                 (( index == index2 )) ||
25557                         error "qos$i on MDT$index, sub on MDT$index2"
25558         done
25559
25560         local testdir=$DIR/$tdir/inherit
25561
25562         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25563         # inherit 2 levels
25564         for i in 1 2; do
25565                 testdir=$testdir/s$i
25566                 mkdir $testdir || error "mkdir $testdir failed"
25567                 index=$($LFS getstripe -m $testdir)
25568                 (( index == 1 )) ||
25569                         error "$testdir on MDT$index"
25570         done
25571
25572         # not inherit any more
25573         testdir=$testdir/s3
25574         mkdir $testdir || error "mkdir $testdir failed"
25575         getfattr -d -m dmv $testdir | grep dmv &&
25576                 error "default LMV set on $testdir" || true
25577 }
25578 run_test 412 "mkdir on specific MDTs"
25579
25580 TEST413_COUNT=${TEST413_COUNT:-200}
25581 generate_uneven_mdts() {
25582         local threshold=$1
25583         local lmv_qos_maxage
25584         local lod_qos_maxage
25585         local ffree
25586         local bavail
25587         local max
25588         local min
25589         local max_index
25590         local min_index
25591         local tmp
25592         local i
25593
25594         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25595         $LCTL set_param lmv.*.qos_maxage=1
25596         stack_trap "$LCTL set_param \
25597                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25598         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25599                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25600         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25601                 lod.*.mdt_qos_maxage=1
25602         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25603                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25604
25605         echo
25606         echo "Check for uneven MDTs: "
25607
25608         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25609         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25610         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25611
25612         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25613         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25614         max_index=0
25615         min_index=0
25616         for ((i = 1; i < ${#ffree[@]}; i++)); do
25617                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25618                 if [ $tmp -gt $max ]; then
25619                         max=$tmp
25620                         max_index=$i
25621                 fi
25622                 if [ $tmp -lt $min ]; then
25623                         min=$tmp
25624                         min_index=$i
25625                 fi
25626         done
25627
25628         (( ${ffree[min_index]} > 0 )) ||
25629                 skip "no free files in MDT$min_index"
25630         (( ${ffree[min_index]} < 10000000 )) ||
25631                 skip "too many free files in MDT$min_index"
25632
25633         # Check if we need to generate uneven MDTs
25634         local diff=$(((max - min) * 100 / min))
25635         local testdir=$DIR/$tdir-fillmdt
25636         local start
25637
25638         i=0
25639         while (( diff < threshold )); do
25640                 mkdir -p $testdir
25641                 # generate uneven MDTs, create till $threshold% diff
25642                 echo -n "weight diff=$diff% must be > $threshold% ..."
25643                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25644                 testdir=$DIR/$tdir-fillmdt/$i
25645                 [ -d $testdir ] && continue
25646                 $LFS mkdir -i $min_index $testdir ||
25647                         error "mkdir $testdir failed"
25648                 $LFS setstripe -E 1M -L mdt $testdir ||
25649                         error "setstripe $testdir failed"
25650                 start=$SECONDS
25651                 for ((F=0; F < TEST413_COUNT; F++)); do
25652                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25653                                 /dev/null 2>&1 || error "dd $F failed"
25654                 done
25655                 sync; sleep 1; sync
25656
25657                 # wait for QOS to update
25658                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25659
25660                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25661                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25662                 max=$(((${ffree[max_index]} >> 8) *
25663                         (${bavail[max_index]} * bsize >> 16)))
25664                 min=$(((${ffree[min_index]} >> 8) *
25665                         (${bavail[min_index]} * bsize >> 16)))
25666                 diff=$(((max - min) * 100 / min))
25667                 i=$((i + 1))
25668         done
25669
25670         echo "MDT filesfree available: ${ffree[*]}"
25671         echo "MDT blocks available: ${bavail[*]}"
25672         echo "weight diff=$diff%"
25673 }
25674
25675 test_qos_mkdir() {
25676         local mkdir_cmd=$1
25677         local stripe_count=$2
25678         local mdts=$(comma_list $(mdts_nodes))
25679
25680         local testdir
25681         local lmv_qos_prio_free
25682         local lmv_qos_threshold_rr
25683         local lmv_qos_maxage
25684         local lod_qos_prio_free
25685         local lod_qos_threshold_rr
25686         local lod_qos_maxage
25687         local count
25688         local i
25689
25690         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25691         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25692         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25693                 head -n1)
25694         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25695         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25696         stack_trap "$LCTL set_param \
25697                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25698         stack_trap "$LCTL set_param \
25699                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25700         stack_trap "$LCTL set_param \
25701                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25702
25703         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25704                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25705         lod_qos_prio_free=${lod_qos_prio_free%%%}
25706         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25707                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25708         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25709         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25710                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25711         stack_trap "do_nodes $mdts $LCTL set_param \
25712                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25713         stack_trap "do_nodes $mdts $LCTL set_param \
25714                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25715         stack_trap "do_nodes $mdts $LCTL set_param \
25716                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25717
25718         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25719         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25720
25721         testdir=$DIR/$tdir-s$stripe_count/rr
25722
25723         local stripe_index=$($LFS getstripe -m $testdir)
25724         local test_mkdir_rr=true
25725
25726         getfattr -d -m dmv -e hex $testdir | grep dmv
25727         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25728                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25729                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25730                         test_mkdir_rr=false
25731         fi
25732
25733         echo
25734         $test_mkdir_rr &&
25735                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25736                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25737
25738         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25739         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25740                 eval $mkdir_cmd $testdir/subdir$i ||
25741                         error "$mkdir_cmd subdir$i failed"
25742         done
25743
25744         for (( i = 0; i < $MDSCOUNT; i++ )); do
25745                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25746                 echo "$count directories created on MDT$i"
25747                 if $test_mkdir_rr; then
25748                         (( $count == 100 )) ||
25749                                 error "subdirs are not evenly distributed"
25750                 elif (( $i == $stripe_index )); then
25751                         (( $count == 100 * MDSCOUNT )) ||
25752                                 error "$count subdirs created on MDT$i"
25753                 else
25754                         (( $count == 0 )) ||
25755                                 error "$count subdirs created on MDT$i"
25756                 fi
25757
25758                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25759                         count=$($LFS getdirstripe $testdir/* |
25760                                 grep -c -P "^\s+$i\t")
25761                         echo "$count stripes created on MDT$i"
25762                         # deviation should < 5% of average
25763                         (( $count >= 95 * stripe_count &&
25764                            $count <= 105 * stripe_count)) ||
25765                                 error "stripes are not evenly distributed"
25766                 fi
25767         done
25768
25769         echo
25770         echo "Check for uneven MDTs: "
25771
25772         local ffree
25773         local bavail
25774         local max
25775         local min
25776         local max_index
25777         local min_index
25778         local tmp
25779
25780         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25781         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25782         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25783
25784         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25785         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25786         max_index=0
25787         min_index=0
25788         for ((i = 1; i < ${#ffree[@]}; i++)); do
25789                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25790                 if [ $tmp -gt $max ]; then
25791                         max=$tmp
25792                         max_index=$i
25793                 fi
25794                 if [ $tmp -lt $min ]; then
25795                         min=$tmp
25796                         min_index=$i
25797                 fi
25798         done
25799
25800         (( ${ffree[min_index]} > 0 )) ||
25801                 skip "no free files in MDT$min_index"
25802         (( ${ffree[min_index]} < 10000000 )) ||
25803                 skip "too many free files in MDT$min_index"
25804
25805         echo "MDT filesfree available: ${ffree[*]}"
25806         echo "MDT blocks available: ${bavail[*]}"
25807         echo "weight diff=$(((max - min) * 100 / min))%"
25808         echo
25809         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25810
25811         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25812         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25813         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25814         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25815         # decrease statfs age, so that it can be updated in time
25816         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25817         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25818
25819         sleep 1
25820
25821         testdir=$DIR/$tdir-s$stripe_count/qos
25822         local num=200
25823
25824         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25825         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25826                 eval $mkdir_cmd $testdir/subdir$i ||
25827                         error "$mkdir_cmd subdir$i failed"
25828         done
25829
25830         max=0
25831         for (( i = 0; i < $MDSCOUNT; i++ )); do
25832                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25833                 (( count > max )) && max=$count
25834                 echo "$count directories created on MDT$i"
25835         done
25836
25837         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25838
25839         # D-value should > 10% of averge
25840         (( max - min > num / 10 )) ||
25841                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25842
25843         # ditto for stripes
25844         if (( stripe_count > 1 )); then
25845                 max=0
25846                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25847                         count=$($LFS getdirstripe $testdir/* |
25848                                 grep -c -P "^\s+$i\t")
25849                         (( count > max )) && max=$count
25850                         echo "$count stripes created on MDT$i"
25851                 done
25852
25853                 min=$($LFS getdirstripe $testdir/* |
25854                         grep -c -P "^\s+$min_index\t")
25855                 (( max - min > num * stripe_count / 10 )) ||
25856                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25857         fi
25858 }
25859
25860 most_full_mdt() {
25861         local ffree
25862         local bavail
25863         local bsize
25864         local min
25865         local min_index
25866         local tmp
25867
25868         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25869         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25870         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25871
25872         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25873         min_index=0
25874         for ((i = 1; i < ${#ffree[@]}; i++)); do
25875                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25876                 (( tmp < min )) && min=$tmp && min_index=$i
25877         done
25878
25879         echo -n $min_index
25880 }
25881
25882 test_413a() {
25883         [ $MDSCOUNT -lt 2 ] &&
25884                 skip "We need at least 2 MDTs for this test"
25885
25886         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25887                 skip "Need server version at least 2.12.52"
25888
25889         local stripe_count
25890
25891         generate_uneven_mdts 100
25892         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25893                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25894                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25895                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25896                         error "mkdir failed"
25897                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25898         done
25899 }
25900 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25901
25902 test_413b() {
25903         [ $MDSCOUNT -lt 2 ] &&
25904                 skip "We need at least 2 MDTs for this test"
25905
25906         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25907                 skip "Need server version at least 2.12.52"
25908
25909         local testdir
25910         local stripe_count
25911
25912         generate_uneven_mdts 100
25913         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25914                 testdir=$DIR/$tdir-s$stripe_count
25915                 mkdir $testdir || error "mkdir $testdir failed"
25916                 mkdir $testdir/rr || error "mkdir rr failed"
25917                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25918                         error "mkdir qos failed"
25919                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25920                         $testdir/rr || error "setdirstripe rr failed"
25921                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25922                         error "setdirstripe failed"
25923                 test_qos_mkdir "mkdir" $stripe_count
25924         done
25925 }
25926 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25927
25928 test_413c() {
25929         (( $MDSCOUNT >= 2 )) ||
25930                 skip "We need at least 2 MDTs for this test"
25931
25932         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25933                 skip "Need server version at least 2.14.51"
25934
25935         local testdir
25936         local inherit
25937         local inherit_rr
25938
25939         testdir=$DIR/${tdir}-s1
25940         mkdir $testdir || error "mkdir $testdir failed"
25941         mkdir $testdir/rr || error "mkdir rr failed"
25942         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25943         # default max_inherit is -1, default max_inherit_rr is 0
25944         $LFS setdirstripe -D -c 1 $testdir/rr ||
25945                 error "setdirstripe rr failed"
25946         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25947                 error "setdirstripe qos failed"
25948         test_qos_mkdir "mkdir" 1
25949
25950         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25951         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25952         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25953         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25954         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25955
25956         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25957         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25958         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25959         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25960         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25961         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25962         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25963                 error "level2 shouldn't have default LMV" || true
25964 }
25965 run_test 413c "mkdir with default LMV max inherit rr"
25966
25967 test_413d() {
25968         (( MDSCOUNT >= 2 )) ||
25969                 skip "We need at least 2 MDTs for this test"
25970
25971         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25972                 skip "Need server version at least 2.14.51"
25973
25974         local lmv_qos_threshold_rr
25975
25976         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25977                 head -n1)
25978         stack_trap "$LCTL set_param \
25979                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25980
25981         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25982         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25983         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25984                 error "$tdir shouldn't have default LMV"
25985         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25986                 error "mkdir sub failed"
25987
25988         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25989
25990         (( count == 100 )) || error "$count subdirs on MDT0"
25991 }
25992 run_test 413d "inherit ROOT default LMV"
25993
25994 test_413e() {
25995         (( MDSCOUNT >= 2 )) ||
25996                 skip "We need at least 2 MDTs for this test"
25997         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25998                 skip "Need server version at least 2.14.55"
25999
26000         local testdir=$DIR/$tdir
26001         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26002         local max_inherit
26003         local sub_max_inherit
26004
26005         mkdir -p $testdir || error "failed to create $testdir"
26006
26007         # set default max-inherit to -1 if stripe count is 0 or 1
26008         $LFS setdirstripe -D -c 1 $testdir ||
26009                 error "failed to set default LMV"
26010         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26011         (( max_inherit == -1 )) ||
26012                 error "wrong max_inherit value $max_inherit"
26013
26014         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26015         $LFS setdirstripe -D -c -1 $testdir ||
26016                 error "failed to set default LMV"
26017         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26018         (( max_inherit > 0 )) ||
26019                 error "wrong max_inherit value $max_inherit"
26020
26021         # and the subdir will decrease the max_inherit by 1
26022         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26023         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26024         (( sub_max_inherit == max_inherit - 1)) ||
26025                 error "wrong max-inherit of subdir $sub_max_inherit"
26026
26027         # check specified --max-inherit and warning message
26028         stack_trap "rm -f $tmpfile"
26029         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26030                 error "failed to set default LMV"
26031         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26032         (( max_inherit == -1 )) ||
26033                 error "wrong max_inherit value $max_inherit"
26034
26035         # check the warning messages
26036         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26037                 error "failed to detect warning string"
26038         fi
26039 }
26040 run_test 413e "check default max-inherit value"
26041
26042 test_fs_dmv_inherit()
26043 {
26044         local testdir=$DIR/$tdir
26045
26046         local count
26047         local inherit
26048         local inherit_rr
26049
26050         for i in 1 2 3; do
26051                 mkdir $testdir || error "mkdir $testdir failed"
26052                 count=$($LFS getdirstripe -D -c $testdir)
26053                 (( count == 1 )) ||
26054                         error "$testdir default LMV count mismatch $count != 1"
26055                 inherit=$($LFS getdirstripe -D -X $testdir)
26056                 (( inherit == 3 - i )) ||
26057                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26058                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26059                 (( inherit_rr == 3 - i )) ||
26060                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26061                 testdir=$testdir/sub
26062         done
26063
26064         mkdir $testdir || error "mkdir $testdir failed"
26065         count=$($LFS getdirstripe -D -c $testdir)
26066         (( count == 0 )) ||
26067                 error "$testdir default LMV count not zero: $count"
26068 }
26069
26070 test_413f() {
26071         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26072
26073         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26074                 skip "Need server version at least 2.14.55"
26075
26076         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26077                 error "dump $DIR default LMV failed"
26078         stack_trap "setfattr --restore=$TMP/dmv.ea"
26079
26080         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26081                 error "set $DIR default LMV failed"
26082
26083         test_fs_dmv_inherit
26084 }
26085 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26086
26087 test_413g() {
26088         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26089
26090         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26091         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26092                 error "dump $DIR default LMV failed"
26093         stack_trap "setfattr --restore=$TMP/dmv.ea"
26094
26095         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26096                 error "set $DIR default LMV failed"
26097
26098         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26099                 error "mount $MOUNT2 failed"
26100         stack_trap "umount_client $MOUNT2"
26101
26102         local saved_DIR=$DIR
26103
26104         export DIR=$MOUNT2
26105
26106         stack_trap "export DIR=$saved_DIR"
26107
26108         # first check filesystem-wide default LMV inheritance
26109         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26110
26111         # then check subdirs are spread to all MDTs
26112         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26113
26114         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26115
26116         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26117 }
26118 run_test 413g "enforce ROOT default LMV on subdir mount"
26119
26120 test_413h() {
26121         (( MDSCOUNT >= 2 )) ||
26122                 skip "We need at least 2 MDTs for this test"
26123
26124         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26125                 skip "Need server version at least 2.15.50.6"
26126
26127         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26128
26129         stack_trap "$LCTL set_param \
26130                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26131         $LCTL set_param lmv.*.qos_maxage=1
26132
26133         local depth=5
26134         local rr_depth=4
26135         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26136         local count=$((MDSCOUNT * 20))
26137
26138         generate_uneven_mdts 50
26139
26140         mkdir -p $dir || error "mkdir $dir failed"
26141         stack_trap "rm -rf $dir"
26142         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26143                 --max-inherit-rr=$rr_depth $dir
26144
26145         for ((d=0; d < depth + 2; d++)); do
26146                 log "dir=$dir:"
26147                 for ((sub=0; sub < count; sub++)); do
26148                         mkdir $dir/d$sub
26149                 done
26150                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26151                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26152                 # subdirs within $rr_depth should be created round-robin
26153                 if (( d < rr_depth )); then
26154                         (( ${num[0]} != count )) ||
26155                                 error "all objects created on MDT ${num[1]}"
26156                 fi
26157
26158                 dir=$dir/d0
26159         done
26160 }
26161 run_test 413h "don't stick to parent for round-robin dirs"
26162
26163 test_413z() {
26164         local pids=""
26165         local subdir
26166         local pid
26167
26168         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26169                 unlinkmany $subdir/f. $TEST413_COUNT &
26170                 pids="$pids $!"
26171         done
26172
26173         for pid in $pids; do
26174                 wait $pid
26175         done
26176 }
26177 run_test 413z "413 test cleanup"
26178
26179 test_414() {
26180 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26181         $LCTL set_param fail_loc=0x80000521
26182         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26183         rm -f $DIR/$tfile
26184 }
26185 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26186
26187 test_415() {
26188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26189         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26190                 skip "Need server version at least 2.11.52"
26191
26192         # LU-11102
26193         local total
26194         local setattr_pid
26195         local start_time
26196         local end_time
26197         local duration
26198
26199         total=500
26200         # this test may be slow on ZFS
26201         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26202
26203         # though this test is designed for striped directory, let's test normal
26204         # directory too since lock is always saved as CoS lock.
26205         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26206         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26207
26208         (
26209                 while true; do
26210                         touch $DIR/$tdir
26211                 done
26212         ) &
26213         setattr_pid=$!
26214
26215         start_time=$(date +%s)
26216         for i in $(seq $total); do
26217                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26218                         > /dev/null
26219         done
26220         end_time=$(date +%s)
26221         duration=$((end_time - start_time))
26222
26223         kill -9 $setattr_pid
26224
26225         echo "rename $total files took $duration sec"
26226         [ $duration -lt 100 ] || error "rename took $duration sec"
26227 }
26228 run_test 415 "lock revoke is not missing"
26229
26230 test_416() {
26231         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26232                 skip "Need server version at least 2.11.55"
26233
26234         # define OBD_FAIL_OSD_TXN_START    0x19a
26235         do_facet mds1 lctl set_param fail_loc=0x19a
26236
26237         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26238
26239         true
26240 }
26241 run_test 416 "transaction start failure won't cause system hung"
26242
26243 cleanup_417() {
26244         trap 0
26245         do_nodes $(comma_list $(mdts_nodes)) \
26246                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26247         do_nodes $(comma_list $(mdts_nodes)) \
26248                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26249         do_nodes $(comma_list $(mdts_nodes)) \
26250                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26251 }
26252
26253 test_417() {
26254         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26255         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26256                 skip "Need MDS version at least 2.11.56"
26257
26258         trap cleanup_417 RETURN EXIT
26259
26260         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26261         do_nodes $(comma_list $(mdts_nodes)) \
26262                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26263         $LFS migrate -m 0 $DIR/$tdir.1 &&
26264                 error "migrate dir $tdir.1 should fail"
26265
26266         do_nodes $(comma_list $(mdts_nodes)) \
26267                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26268         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26269                 error "create remote dir $tdir.2 should fail"
26270
26271         do_nodes $(comma_list $(mdts_nodes)) \
26272                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26273         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26274                 error "create striped dir $tdir.3 should fail"
26275         true
26276 }
26277 run_test 417 "disable remote dir, striped dir and dir migration"
26278
26279 # Checks that the outputs of df [-i] and lfs df [-i] match
26280 #
26281 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26282 check_lfs_df() {
26283         local dir=$2
26284         local inodes
26285         local df_out
26286         local lfs_df_out
26287         local count
26288         local passed=false
26289
26290         # blocks or inodes
26291         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26292
26293         for count in {1..100}; do
26294                 do_nodes "$CLIENTS" \
26295                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26296                 sync; sleep 0.2
26297
26298                 # read the lines of interest
26299                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26300                         error "df $inodes $dir | tail -n +2 failed"
26301                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26302                         error "lfs df $inodes $dir | grep summary: failed"
26303
26304                 # skip first substrings of each output as they are different
26305                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26306                 # compare the two outputs
26307                 passed=true
26308                 #  skip "available" on MDT until LU-13997 is fixed.
26309                 #for i in {1..5}; do
26310                 for i in 1 2 4 5; do
26311                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26312                 done
26313                 $passed && break
26314         done
26315
26316         if ! $passed; then
26317                 df -P $inodes $dir
26318                 echo
26319                 lfs df $inodes $dir
26320                 error "df and lfs df $1 output mismatch: "      \
26321                       "df ${inodes}: ${df_out[*]}, "            \
26322                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26323         fi
26324 }
26325
26326 test_418() {
26327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26328
26329         local dir=$DIR/$tdir
26330         local numfiles=$((RANDOM % 4096 + 2))
26331         local numblocks=$((RANDOM % 256 + 1))
26332
26333         wait_delete_completed
26334         test_mkdir $dir
26335
26336         # check block output
26337         check_lfs_df blocks $dir
26338         # check inode output
26339         check_lfs_df inodes $dir
26340
26341         # create a single file and retest
26342         echo "Creating a single file and testing"
26343         createmany -o $dir/$tfile- 1 &>/dev/null ||
26344                 error "creating 1 file in $dir failed"
26345         check_lfs_df blocks $dir
26346         check_lfs_df inodes $dir
26347
26348         # create a random number of files
26349         echo "Creating $((numfiles - 1)) files and testing"
26350         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26351                 error "creating $((numfiles - 1)) files in $dir failed"
26352
26353         # write a random number of blocks to the first test file
26354         echo "Writing $numblocks 4K blocks and testing"
26355         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26356                 count=$numblocks &>/dev/null ||
26357                 error "dd to $dir/${tfile}-0 failed"
26358
26359         # retest
26360         check_lfs_df blocks $dir
26361         check_lfs_df inodes $dir
26362
26363         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26364                 error "unlinking $numfiles files in $dir failed"
26365 }
26366 run_test 418 "df and lfs df outputs match"
26367
26368 test_419()
26369 {
26370         local dir=$DIR/$tdir
26371
26372         mkdir -p $dir
26373         touch $dir/file
26374
26375         cancel_lru_locks mdc
26376
26377         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26378         $LCTL set_param fail_loc=0x1410
26379         cat $dir/file
26380         $LCTL set_param fail_loc=0
26381         rm -rf $dir
26382 }
26383 run_test 419 "Verify open file by name doesn't crash kernel"
26384
26385 test_420()
26386 {
26387         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26388                 skip "Need MDS version at least 2.12.53"
26389
26390         local SAVE_UMASK=$(umask)
26391         local dir=$DIR/$tdir
26392         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26393
26394         mkdir -p $dir
26395         umask 0000
26396         mkdir -m03777 $dir/testdir
26397         ls -dn $dir/testdir
26398         # Need to remove trailing '.' when SELinux is enabled
26399         local dirperms=$(ls -dn $dir/testdir |
26400                          awk '{ sub(/\.$/, "", $1); print $1}')
26401         [ $dirperms == "drwxrwsrwt" ] ||
26402                 error "incorrect perms on $dir/testdir"
26403
26404         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26405                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26406         ls -n $dir/testdir/testfile
26407         local fileperms=$(ls -n $dir/testdir/testfile |
26408                           awk '{ sub(/\.$/, "", $1); print $1}')
26409         [ $fileperms == "-rwxr-xr-x" ] ||
26410                 error "incorrect perms on $dir/testdir/testfile"
26411
26412         umask $SAVE_UMASK
26413 }
26414 run_test 420 "clear SGID bit on non-directories for non-members"
26415
26416 test_421a() {
26417         local cnt
26418         local fid1
26419         local fid2
26420
26421         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26422                 skip "Need MDS version at least 2.12.54"
26423
26424         test_mkdir $DIR/$tdir
26425         createmany -o $DIR/$tdir/f 3
26426         cnt=$(ls -1 $DIR/$tdir | wc -l)
26427         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26428
26429         fid1=$(lfs path2fid $DIR/$tdir/f1)
26430         fid2=$(lfs path2fid $DIR/$tdir/f2)
26431         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26432
26433         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26434         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26435
26436         cnt=$(ls -1 $DIR/$tdir | wc -l)
26437         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26438
26439         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26440         createmany -o $DIR/$tdir/f 3
26441         cnt=$(ls -1 $DIR/$tdir | wc -l)
26442         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26443
26444         fid1=$(lfs path2fid $DIR/$tdir/f1)
26445         fid2=$(lfs path2fid $DIR/$tdir/f2)
26446         echo "remove using fsname $FSNAME"
26447         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26448
26449         cnt=$(ls -1 $DIR/$tdir | wc -l)
26450         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26451 }
26452 run_test 421a "simple rm by fid"
26453
26454 test_421b() {
26455         local cnt
26456         local FID1
26457         local FID2
26458
26459         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26460                 skip "Need MDS version at least 2.12.54"
26461
26462         test_mkdir $DIR/$tdir
26463         createmany -o $DIR/$tdir/f 3
26464         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26465         MULTIPID=$!
26466
26467         FID1=$(lfs path2fid $DIR/$tdir/f1)
26468         FID2=$(lfs path2fid $DIR/$tdir/f2)
26469         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26470
26471         kill -USR1 $MULTIPID
26472         wait
26473
26474         cnt=$(ls $DIR/$tdir | wc -l)
26475         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26476 }
26477 run_test 421b "rm by fid on open file"
26478
26479 test_421c() {
26480         local cnt
26481         local FIDS
26482
26483         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26484                 skip "Need MDS version at least 2.12.54"
26485
26486         test_mkdir $DIR/$tdir
26487         createmany -o $DIR/$tdir/f 3
26488         touch $DIR/$tdir/$tfile
26489         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26490         cnt=$(ls -1 $DIR/$tdir | wc -l)
26491         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26492
26493         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26494         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26495
26496         cnt=$(ls $DIR/$tdir | wc -l)
26497         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26498 }
26499 run_test 421c "rm by fid against hardlinked files"
26500
26501 test_421d() {
26502         local cnt
26503         local FIDS
26504
26505         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26506                 skip "Need MDS version at least 2.12.54"
26507
26508         test_mkdir $DIR/$tdir
26509         createmany -o $DIR/$tdir/f 4097
26510         cnt=$(ls -1 $DIR/$tdir | wc -l)
26511         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26512
26513         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26514         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26515
26516         cnt=$(ls $DIR/$tdir | wc -l)
26517         rm -rf $DIR/$tdir
26518         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26519 }
26520 run_test 421d "rmfid en masse"
26521
26522 test_421e() {
26523         local cnt
26524         local FID
26525
26526         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26527         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26528                 skip "Need MDS version at least 2.12.54"
26529
26530         mkdir -p $DIR/$tdir
26531         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26532         createmany -o $DIR/$tdir/striped_dir/f 512
26533         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26534         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26535
26536         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26537                 sed "s/[/][^:]*://g")
26538         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26539
26540         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26541         rm -rf $DIR/$tdir
26542         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26543 }
26544 run_test 421e "rmfid in DNE"
26545
26546 test_421f() {
26547         local cnt
26548         local FID
26549
26550         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26551                 skip "Need MDS version at least 2.12.54"
26552
26553         test_mkdir $DIR/$tdir
26554         touch $DIR/$tdir/f
26555         cnt=$(ls -1 $DIR/$tdir | wc -l)
26556         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26557
26558         FID=$(lfs path2fid $DIR/$tdir/f)
26559         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26560         # rmfid should fail
26561         cnt=$(ls -1 $DIR/$tdir | wc -l)
26562         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26563
26564         chmod a+rw $DIR/$tdir
26565         ls -la $DIR/$tdir
26566         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26567         # rmfid should fail
26568         cnt=$(ls -1 $DIR/$tdir | wc -l)
26569         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26570
26571         rm -f $DIR/$tdir/f
26572         $RUNAS touch $DIR/$tdir/f
26573         FID=$(lfs path2fid $DIR/$tdir/f)
26574         echo "rmfid as root"
26575         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26576         cnt=$(ls -1 $DIR/$tdir | wc -l)
26577         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26578
26579         rm -f $DIR/$tdir/f
26580         $RUNAS touch $DIR/$tdir/f
26581         cnt=$(ls -1 $DIR/$tdir | wc -l)
26582         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26583         FID=$(lfs path2fid $DIR/$tdir/f)
26584         # rmfid w/o user_fid2path mount option should fail
26585         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26586         cnt=$(ls -1 $DIR/$tdir | wc -l)
26587         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26588
26589         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26590         stack_trap "rmdir $tmpdir"
26591         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26592                 error "failed to mount client'"
26593         stack_trap "umount_client $tmpdir"
26594
26595         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26596         # rmfid should succeed
26597         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26598         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26599
26600         # rmfid shouldn't allow to remove files due to dir's permission
26601         chmod a+rwx $tmpdir/$tdir
26602         touch $tmpdir/$tdir/f
26603         ls -la $tmpdir/$tdir
26604         FID=$(lfs path2fid $tmpdir/$tdir/f)
26605         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26606         return 0
26607 }
26608 run_test 421f "rmfid checks permissions"
26609
26610 test_421g() {
26611         local cnt
26612         local FIDS
26613
26614         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26615         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26616                 skip "Need MDS version at least 2.12.54"
26617
26618         mkdir -p $DIR/$tdir
26619         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26620         createmany -o $DIR/$tdir/striped_dir/f 512
26621         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26622         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26623
26624         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26625                 sed "s/[/][^:]*://g")
26626
26627         rm -f $DIR/$tdir/striped_dir/f1*
26628         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26629         removed=$((512 - cnt))
26630
26631         # few files have been just removed, so we expect
26632         # rmfid to fail on their fids
26633         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26634         [ $removed != $errors ] && error "$errors != $removed"
26635
26636         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26637         rm -rf $DIR/$tdir
26638         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26639 }
26640 run_test 421g "rmfid to return errors properly"
26641
26642 test_422() {
26643         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26644         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26645         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26646         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26647         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26648
26649         local amc=$(at_max_get client)
26650         local amo=$(at_max_get mds1)
26651         local timeout=`lctl get_param -n timeout`
26652
26653         at_max_set 0 client
26654         at_max_set 0 mds1
26655
26656 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26657         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26658                         fail_val=$(((2*timeout + 10)*1000))
26659         touch $DIR/$tdir/d3/file &
26660         sleep 2
26661 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26662         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26663                         fail_val=$((2*timeout + 5))
26664         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26665         local pid=$!
26666         sleep 1
26667         kill -9 $pid
26668         sleep $((2 * timeout))
26669         echo kill $pid
26670         kill -9 $pid
26671         lctl mark touch
26672         touch $DIR/$tdir/d2/file3
26673         touch $DIR/$tdir/d2/file4
26674         touch $DIR/$tdir/d2/file5
26675
26676         wait
26677         at_max_set $amc client
26678         at_max_set $amo mds1
26679
26680         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26681         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26682                 error "Watchdog is always throttled"
26683 }
26684 run_test 422 "kill a process with RPC in progress"
26685
26686 stat_test() {
26687     df -h $MOUNT &
26688     df -h $MOUNT &
26689     df -h $MOUNT &
26690     df -h $MOUNT &
26691     df -h $MOUNT &
26692     df -h $MOUNT &
26693 }
26694
26695 test_423() {
26696     local _stats
26697     # ensure statfs cache is expired
26698     sleep 2;
26699
26700     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26701     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26702
26703     return 0
26704 }
26705 run_test 423 "statfs should return a right data"
26706
26707 test_424() {
26708 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26709         $LCTL set_param fail_loc=0x80000522
26710         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26711         rm -f $DIR/$tfile
26712 }
26713 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26714
26715 test_425() {
26716         test_mkdir -c -1 $DIR/$tdir
26717         $LFS setstripe -c -1 $DIR/$tdir
26718
26719         lru_resize_disable "" 100
26720         stack_trap "lru_resize_enable" EXIT
26721
26722         sleep 5
26723
26724         for i in $(seq $((MDSCOUNT * 125))); do
26725                 local t=$DIR/$tdir/$tfile_$i
26726
26727                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26728                         error_noexit "Create file $t"
26729         done
26730         stack_trap "rm -rf $DIR/$tdir" EXIT
26731
26732         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26733                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26734                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26735
26736                 [ $lock_count -le $lru_size ] ||
26737                         error "osc lock count $lock_count > lru size $lru_size"
26738         done
26739
26740         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26741                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26742                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26743
26744                 [ $lock_count -le $lru_size ] ||
26745                         error "mdc lock count $lock_count > lru size $lru_size"
26746         done
26747 }
26748 run_test 425 "lock count should not exceed lru size"
26749
26750 test_426() {
26751         splice-test -r $DIR/$tfile
26752         splice-test -rd $DIR/$tfile
26753         splice-test $DIR/$tfile
26754         splice-test -d $DIR/$tfile
26755 }
26756 run_test 426 "splice test on Lustre"
26757
26758 test_427() {
26759         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26760         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26761                 skip "Need MDS version at least 2.12.4"
26762         local log
26763
26764         mkdir $DIR/$tdir
26765         mkdir $DIR/$tdir/1
26766         mkdir $DIR/$tdir/2
26767         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26768         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26769
26770         $LFS getdirstripe $DIR/$tdir/1/dir
26771
26772         #first setfattr for creating updatelog
26773         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26774
26775 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26776         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26777         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26778         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26779
26780         sleep 2
26781         fail mds2
26782         wait_recovery_complete mds2 $((2*TIMEOUT))
26783
26784         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26785         echo $log | grep "get update log failed" &&
26786                 error "update log corruption is detected" || true
26787 }
26788 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26789
26790 test_428() {
26791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26792         local cache_limit=$CACHE_MAX
26793
26794         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26795         $LCTL set_param -n llite.*.max_cached_mb=64
26796
26797         mkdir $DIR/$tdir
26798         $LFS setstripe -c 1 $DIR/$tdir
26799         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26800         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26801         #test write
26802         for f in $(seq 4); do
26803                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26804         done
26805         wait
26806
26807         cancel_lru_locks osc
26808         # Test read
26809         for f in $(seq 4); do
26810                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26811         done
26812         wait
26813 }
26814 run_test 428 "large block size IO should not hang"
26815
26816 test_429() { # LU-7915 / LU-10948
26817         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26818         local testfile=$DIR/$tfile
26819         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26820         local new_flag=1
26821         local first_rpc
26822         local second_rpc
26823         local third_rpc
26824
26825         $LCTL get_param $ll_opencache_threshold_count ||
26826                 skip "client does not have opencache parameter"
26827
26828         set_opencache $new_flag
26829         stack_trap "restore_opencache"
26830         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26831                 error "enable opencache failed"
26832         touch $testfile
26833         # drop MDC DLM locks
26834         cancel_lru_locks mdc
26835         # clear MDC RPC stats counters
26836         $LCTL set_param $mdc_rpcstats=clear
26837
26838         # According to the current implementation, we need to run 3 times
26839         # open & close file to verify if opencache is enabled correctly.
26840         # 1st, RPCs are sent for lookup/open and open handle is released on
26841         #      close finally.
26842         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26843         #      so open handle won't be released thereafter.
26844         # 3rd, No RPC is sent out.
26845         $MULTIOP $testfile oc || error "multiop failed"
26846         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26847         echo "1st: $first_rpc RPCs in flight"
26848
26849         $MULTIOP $testfile oc || error "multiop failed"
26850         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26851         echo "2nd: $second_rpc RPCs in flight"
26852
26853         $MULTIOP $testfile oc || error "multiop failed"
26854         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26855         echo "3rd: $third_rpc RPCs in flight"
26856
26857         #verify no MDC RPC is sent
26858         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26859 }
26860 run_test 429 "verify if opencache flag on client side does work"
26861
26862 lseek_test_430() {
26863         local offset
26864         local file=$1
26865
26866         # data at [200K, 400K)
26867         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26868                 error "256K->512K dd fails"
26869         # data at [2M, 3M)
26870         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26871                 error "2M->3M dd fails"
26872         # data at [4M, 5M)
26873         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26874                 error "4M->5M dd fails"
26875         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26876         # start at first component hole #1
26877         printf "Seeking hole from 1000 ... "
26878         offset=$(lseek_test -l 1000 $file)
26879         echo $offset
26880         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26881         printf "Seeking data from 1000 ... "
26882         offset=$(lseek_test -d 1000 $file)
26883         echo $offset
26884         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26885
26886         # start at first component data block
26887         printf "Seeking hole from 300000 ... "
26888         offset=$(lseek_test -l 300000 $file)
26889         echo $offset
26890         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26891         printf "Seeking data from 300000 ... "
26892         offset=$(lseek_test -d 300000 $file)
26893         echo $offset
26894         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26895
26896         # start at the first component but beyond end of object size
26897         printf "Seeking hole from 1000000 ... "
26898         offset=$(lseek_test -l 1000000 $file)
26899         echo $offset
26900         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26901         printf "Seeking data from 1000000 ... "
26902         offset=$(lseek_test -d 1000000 $file)
26903         echo $offset
26904         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26905
26906         # start at second component stripe 2 (empty file)
26907         printf "Seeking hole from 1500000 ... "
26908         offset=$(lseek_test -l 1500000 $file)
26909         echo $offset
26910         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26911         printf "Seeking data from 1500000 ... "
26912         offset=$(lseek_test -d 1500000 $file)
26913         echo $offset
26914         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26915
26916         # start at second component stripe 1 (all data)
26917         printf "Seeking hole from 3000000 ... "
26918         offset=$(lseek_test -l 3000000 $file)
26919         echo $offset
26920         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26921         printf "Seeking data from 3000000 ... "
26922         offset=$(lseek_test -d 3000000 $file)
26923         echo $offset
26924         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26925
26926         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26927                 error "2nd dd fails"
26928         echo "Add data block at 640K...1280K"
26929
26930         # start at before new data block, in hole
26931         printf "Seeking hole from 600000 ... "
26932         offset=$(lseek_test -l 600000 $file)
26933         echo $offset
26934         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26935         printf "Seeking data from 600000 ... "
26936         offset=$(lseek_test -d 600000 $file)
26937         echo $offset
26938         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26939
26940         # start at the first component new data block
26941         printf "Seeking hole from 1000000 ... "
26942         offset=$(lseek_test -l 1000000 $file)
26943         echo $offset
26944         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26945         printf "Seeking data from 1000000 ... "
26946         offset=$(lseek_test -d 1000000 $file)
26947         echo $offset
26948         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26949
26950         # start at second component stripe 2, new data
26951         printf "Seeking hole from 1200000 ... "
26952         offset=$(lseek_test -l 1200000 $file)
26953         echo $offset
26954         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26955         printf "Seeking data from 1200000 ... "
26956         offset=$(lseek_test -d 1200000 $file)
26957         echo $offset
26958         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26959
26960         # start beyond file end
26961         printf "Using offset > filesize ... "
26962         lseek_test -l 4000000 $file && error "lseek should fail"
26963         printf "Using offset > filesize ... "
26964         lseek_test -d 4000000 $file && error "lseek should fail"
26965
26966         printf "Done\n\n"
26967 }
26968
26969 test_430a() {
26970         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26971                 skip "MDT does not support SEEK_HOLE"
26972
26973         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26974                 skip "OST does not support SEEK_HOLE"
26975
26976         local file=$DIR/$tdir/$tfile
26977
26978         mkdir -p $DIR/$tdir
26979
26980         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26981         # OST stripe #1 will have continuous data at [1M, 3M)
26982         # OST stripe #2 is empty
26983         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26984         lseek_test_430 $file
26985         rm $file
26986         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26987         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26988         lseek_test_430 $file
26989         rm $file
26990         $LFS setstripe -c2 -S 512K $file
26991         echo "Two stripes, stripe size 512K"
26992         lseek_test_430 $file
26993         rm $file
26994         # FLR with stale mirror
26995         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26996                        -N -c2 -S 1M $file
26997         echo "Mirrored file:"
26998         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26999         echo "Plain 2 stripes 1M"
27000         lseek_test_430 $file
27001         rm $file
27002 }
27003 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27004
27005 test_430b() {
27006         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27007                 skip "OST does not support SEEK_HOLE"
27008
27009         local offset
27010         local file=$DIR/$tdir/$tfile
27011
27012         mkdir -p $DIR/$tdir
27013         # Empty layout lseek should fail
27014         $MCREATE $file
27015         # seek from 0
27016         printf "Seeking hole from 0 ... "
27017         lseek_test -l 0 $file && error "lseek should fail"
27018         printf "Seeking data from 0 ... "
27019         lseek_test -d 0 $file && error "lseek should fail"
27020         rm $file
27021
27022         # 1M-hole file
27023         $LFS setstripe -E 1M -c2 -E eof $file
27024         $TRUNCATE $file 1048576
27025         printf "Seeking hole from 1000000 ... "
27026         offset=$(lseek_test -l 1000000 $file)
27027         echo $offset
27028         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27029         printf "Seeking data from 1000000 ... "
27030         lseek_test -d 1000000 $file && error "lseek should fail"
27031         rm $file
27032
27033         # full component followed by non-inited one
27034         $LFS setstripe -E 1M -c2 -E eof $file
27035         dd if=/dev/urandom of=$file bs=1M count=1
27036         printf "Seeking hole from 1000000 ... "
27037         offset=$(lseek_test -l 1000000 $file)
27038         echo $offset
27039         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27040         printf "Seeking hole from 1048576 ... "
27041         lseek_test -l 1048576 $file && error "lseek should fail"
27042         # init second component and truncate back
27043         echo "123" >> $file
27044         $TRUNCATE $file 1048576
27045         printf "Seeking hole from 1000000 ... "
27046         offset=$(lseek_test -l 1000000 $file)
27047         echo $offset
27048         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27049         printf "Seeking hole from 1048576 ... "
27050         lseek_test -l 1048576 $file && error "lseek should fail"
27051         # boundary checks for big values
27052         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27053         offset=$(lseek_test -d 0 $file.10g)
27054         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27055         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27056         offset=$(lseek_test -d 0 $file.100g)
27057         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27058         return 0
27059 }
27060 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27061
27062 test_430c() {
27063         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27064                 skip "OST does not support SEEK_HOLE"
27065
27066         local file=$DIR/$tdir/$tfile
27067         local start
27068
27069         mkdir -p $DIR/$tdir
27070         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27071
27072         # cp version 8.33+ prefers lseek over fiemap
27073         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27074                 start=$SECONDS
27075                 time cp $file /dev/null
27076                 (( SECONDS - start < 5 )) ||
27077                         error "cp: too long runtime $((SECONDS - start))"
27078
27079         fi
27080         # tar version 1.29+ supports SEEK_HOLE/DATA
27081         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27082                 start=$SECONDS
27083                 time tar cS $file - | cat > /dev/null
27084                 (( SECONDS - start < 5 )) ||
27085                         error "tar: too long runtime $((SECONDS - start))"
27086         fi
27087 }
27088 run_test 430c "lseek: external tools check"
27089
27090 test_431() { # LU-14187
27091         local file=$DIR/$tdir/$tfile
27092
27093         mkdir -p $DIR/$tdir
27094         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27095         dd if=/dev/urandom of=$file bs=4k count=1
27096         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27097         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27098         #define OBD_FAIL_OST_RESTART_IO 0x251
27099         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27100         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27101         cp $file $file.0
27102         cancel_lru_locks
27103         sync_all_data
27104         echo 3 > /proc/sys/vm/drop_caches
27105         diff  $file $file.0 || error "data diff"
27106 }
27107 run_test 431 "Restart transaction for IO"
27108
27109 cleanup_test_432() {
27110         do_facet mgs $LCTL nodemap_activate 0
27111         wait_nm_sync active
27112 }
27113
27114 test_432() {
27115         local tmpdir=$TMP/dir432
27116
27117         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27118                 skip "Need MDS version at least 2.14.52"
27119
27120         stack_trap cleanup_test_432 EXIT
27121         mkdir $DIR/$tdir
27122         mkdir $tmpdir
27123
27124         do_facet mgs $LCTL nodemap_activate 1
27125         wait_nm_sync active
27126         do_facet mgs $LCTL nodemap_modify --name default \
27127                 --property admin --value 1
27128         do_facet mgs $LCTL nodemap_modify --name default \
27129                 --property trusted --value 1
27130         cancel_lru_locks mdc
27131         wait_nm_sync default admin_nodemap
27132         wait_nm_sync default trusted_nodemap
27133
27134         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27135                grep -ci "Operation not permitted") -ne 0 ]; then
27136                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27137         fi
27138 }
27139 run_test 432 "mv dir from outside Lustre"
27140
27141 test_433() {
27142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27143
27144         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27145                 skip "inode cache not supported"
27146
27147         $LCTL set_param llite.*.inode_cache=0
27148         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27149
27150         local count=256
27151         local before
27152         local after
27153
27154         cancel_lru_locks mdc
27155         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27156         createmany -m $DIR/$tdir/f $count
27157         createmany -d $DIR/$tdir/d $count
27158         ls -l $DIR/$tdir > /dev/null
27159         stack_trap "rm -rf $DIR/$tdir"
27160
27161         before=$(num_objects)
27162         cancel_lru_locks mdc
27163         after=$(num_objects)
27164
27165         # sometimes even @before is less than 2 * count
27166         while (( before - after < count )); do
27167                 sleep 1
27168                 after=$(num_objects)
27169                 wait=$((wait + 1))
27170                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27171                 if (( wait > 60 )); then
27172                         error "inode slab grew from $before to $after"
27173                 fi
27174         done
27175
27176         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27177 }
27178 run_test 433 "ldlm lock cancel releases dentries and inodes"
27179
27180 prep_801() {
27181         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27182         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27183                 skip "Need server version at least 2.9.55"
27184
27185         start_full_debug_logging
27186 }
27187
27188 post_801() {
27189         stop_full_debug_logging
27190 }
27191
27192 barrier_stat() {
27193         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27194                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27195                            awk '/The barrier for/ { print $7 }')
27196                 echo $st
27197         else
27198                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27199                 echo \'$st\'
27200         fi
27201 }
27202
27203 barrier_expired() {
27204         local expired
27205
27206         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27207                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27208                           awk '/will be expired/ { print $7 }')
27209         else
27210                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27211         fi
27212
27213         echo $expired
27214 }
27215
27216 test_801a() {
27217         prep_801
27218
27219         echo "Start barrier_freeze at: $(date)"
27220         #define OBD_FAIL_BARRIER_DELAY          0x2202
27221         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27222         # Do not reduce barrier time - See LU-11873
27223         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27224
27225         sleep 2
27226         local b_status=$(barrier_stat)
27227         echo "Got barrier status at: $(date)"
27228         [ "$b_status" = "'freezing_p1'" ] ||
27229                 error "(1) unexpected barrier status $b_status"
27230
27231         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27232         wait
27233         b_status=$(barrier_stat)
27234         [ "$b_status" = "'frozen'" ] ||
27235                 error "(2) unexpected barrier status $b_status"
27236
27237         local expired=$(barrier_expired)
27238         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27239         sleep $((expired + 3))
27240
27241         b_status=$(barrier_stat)
27242         [ "$b_status" = "'expired'" ] ||
27243                 error "(3) unexpected barrier status $b_status"
27244
27245         # Do not reduce barrier time - See LU-11873
27246         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27247                 error "(4) fail to freeze barrier"
27248
27249         b_status=$(barrier_stat)
27250         [ "$b_status" = "'frozen'" ] ||
27251                 error "(5) unexpected barrier status $b_status"
27252
27253         echo "Start barrier_thaw at: $(date)"
27254         #define OBD_FAIL_BARRIER_DELAY          0x2202
27255         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27256         do_facet mgs $LCTL barrier_thaw $FSNAME &
27257
27258         sleep 2
27259         b_status=$(barrier_stat)
27260         echo "Got barrier status at: $(date)"
27261         [ "$b_status" = "'thawing'" ] ||
27262                 error "(6) unexpected barrier status $b_status"
27263
27264         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27265         wait
27266         b_status=$(barrier_stat)
27267         [ "$b_status" = "'thawed'" ] ||
27268                 error "(7) unexpected barrier status $b_status"
27269
27270         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27271         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27272         do_facet mgs $LCTL barrier_freeze $FSNAME
27273
27274         b_status=$(barrier_stat)
27275         [ "$b_status" = "'failed'" ] ||
27276                 error "(8) unexpected barrier status $b_status"
27277
27278         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27279         do_facet mgs $LCTL barrier_thaw $FSNAME
27280
27281         post_801
27282 }
27283 run_test 801a "write barrier user interfaces and stat machine"
27284
27285 test_801b() {
27286         prep_801
27287
27288         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27289         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27290         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27291         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27292         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27293
27294         cancel_lru_locks mdc
27295
27296         # 180 seconds should be long enough
27297         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27298
27299         local b_status=$(barrier_stat)
27300         [ "$b_status" = "'frozen'" ] ||
27301                 error "(6) unexpected barrier status $b_status"
27302
27303         mkdir $DIR/$tdir/d0/d10 &
27304         mkdir_pid=$!
27305
27306         touch $DIR/$tdir/d1/f13 &
27307         touch_pid=$!
27308
27309         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27310         ln_pid=$!
27311
27312         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27313         mv_pid=$!
27314
27315         rm -f $DIR/$tdir/d4/f12 &
27316         rm_pid=$!
27317
27318         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27319
27320         # To guarantee taht the 'stat' is not blocked
27321         b_status=$(barrier_stat)
27322         [ "$b_status" = "'frozen'" ] ||
27323                 error "(8) unexpected barrier status $b_status"
27324
27325         # let above commands to run at background
27326         sleep 5
27327
27328         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27329         ps -p $touch_pid || error "(10) touch should be blocked"
27330         ps -p $ln_pid || error "(11) link should be blocked"
27331         ps -p $mv_pid || error "(12) rename should be blocked"
27332         ps -p $rm_pid || error "(13) unlink should be blocked"
27333
27334         b_status=$(barrier_stat)
27335         [ "$b_status" = "'frozen'" ] ||
27336                 error "(14) unexpected barrier status $b_status"
27337
27338         do_facet mgs $LCTL barrier_thaw $FSNAME
27339         b_status=$(barrier_stat)
27340         [ "$b_status" = "'thawed'" ] ||
27341                 error "(15) unexpected barrier status $b_status"
27342
27343         wait $mkdir_pid || error "(16) mkdir should succeed"
27344         wait $touch_pid || error "(17) touch should succeed"
27345         wait $ln_pid || error "(18) link should succeed"
27346         wait $mv_pid || error "(19) rename should succeed"
27347         wait $rm_pid || error "(20) unlink should succeed"
27348
27349         post_801
27350 }
27351 run_test 801b "modification will be blocked by write barrier"
27352
27353 test_801c() {
27354         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27355
27356         prep_801
27357
27358         stop mds2 || error "(1) Fail to stop mds2"
27359
27360         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27361
27362         local b_status=$(barrier_stat)
27363         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27364                 do_facet mgs $LCTL barrier_thaw $FSNAME
27365                 error "(2) unexpected barrier status $b_status"
27366         }
27367
27368         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27369                 error "(3) Fail to rescan barrier bitmap"
27370
27371         # Do not reduce barrier time - See LU-11873
27372         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27373
27374         b_status=$(barrier_stat)
27375         [ "$b_status" = "'frozen'" ] ||
27376                 error "(4) unexpected barrier status $b_status"
27377
27378         do_facet mgs $LCTL barrier_thaw $FSNAME
27379         b_status=$(barrier_stat)
27380         [ "$b_status" = "'thawed'" ] ||
27381                 error "(5) unexpected barrier status $b_status"
27382
27383         local devname=$(mdsdevname 2)
27384
27385         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27386
27387         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27388                 error "(7) Fail to rescan barrier bitmap"
27389
27390         post_801
27391 }
27392 run_test 801c "rescan barrier bitmap"
27393
27394 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27395 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27396 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27397 saved_MOUNT_OPTS=$MOUNT_OPTS
27398
27399 cleanup_802a() {
27400         trap 0
27401
27402         stopall
27403         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27404         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27405         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27406         MOUNT_OPTS=$saved_MOUNT_OPTS
27407         setupall
27408 }
27409
27410 test_802a() {
27411         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27412         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27413         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27414                 skip "Need server version at least 2.9.55"
27415
27416         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27417
27418         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27419
27420         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27421                 error "(2) Fail to copy"
27422
27423         trap cleanup_802a EXIT
27424
27425         # sync by force before remount as readonly
27426         sync; sync_all_data; sleep 3; sync_all_data
27427
27428         stopall
27429
27430         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27431         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27432         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27433
27434         echo "Mount the server as read only"
27435         setupall server_only || error "(3) Fail to start servers"
27436
27437         echo "Mount client without ro should fail"
27438         mount_client $MOUNT &&
27439                 error "(4) Mount client without 'ro' should fail"
27440
27441         echo "Mount client with ro should succeed"
27442         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27443         mount_client $MOUNT ||
27444                 error "(5) Mount client with 'ro' should succeed"
27445
27446         echo "Modify should be refused"
27447         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27448
27449         echo "Read should be allowed"
27450         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27451                 error "(7) Read should succeed under ro mode"
27452
27453         cleanup_802a
27454 }
27455 run_test 802a "simulate readonly device"
27456
27457 test_802b() {
27458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27459         remote_mds_nodsh && skip "remote MDS with nodsh"
27460
27461         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27462                 skip "readonly option not available"
27463
27464         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27465
27466         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27467                 error "(2) Fail to copy"
27468
27469         # write back all cached data before setting MDT to readonly
27470         cancel_lru_locks
27471         sync_all_data
27472
27473         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27474         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27475
27476         echo "Modify should be refused"
27477         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27478
27479         echo "Read should be allowed"
27480         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27481                 error "(7) Read should succeed under ro mode"
27482
27483         # disable readonly
27484         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27485 }
27486 run_test 802b "be able to set MDTs to readonly"
27487
27488 test_803a() {
27489         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27490         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27491                 skip "MDS needs to be newer than 2.10.54"
27492
27493         mkdir_on_mdt0 $DIR/$tdir
27494         # Create some objects on all MDTs to trigger related logs objects
27495         for idx in $(seq $MDSCOUNT); do
27496                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27497                         $DIR/$tdir/dir${idx} ||
27498                         error "Fail to create $DIR/$tdir/dir${idx}"
27499         done
27500
27501         sync; sleep 3
27502         wait_delete_completed # ensure old test cleanups are finished
27503         echo "before create:"
27504         $LFS df -i $MOUNT
27505         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27506
27507         for i in {1..10}; do
27508                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27509                         error "Fail to create $DIR/$tdir/foo$i"
27510         done
27511
27512         sync; sleep 3
27513         echo "after create:"
27514         $LFS df -i $MOUNT
27515         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27516
27517         # allow for an llog to be cleaned up during the test
27518         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27519                 error "before ($before_used) + 10 > after ($after_used)"
27520
27521         for i in {1..10}; do
27522                 rm -rf $DIR/$tdir/foo$i ||
27523                         error "Fail to remove $DIR/$tdir/foo$i"
27524         done
27525
27526         sleep 3 # avoid MDT return cached statfs
27527         wait_delete_completed
27528         echo "after unlink:"
27529         $LFS df -i $MOUNT
27530         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27531
27532         # allow for an llog to be created during the test
27533         [ $after_used -le $((before_used + 1)) ] ||
27534                 error "after ($after_used) > before ($before_used) + 1"
27535 }
27536 run_test 803a "verify agent object for remote object"
27537
27538 test_803b() {
27539         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27540         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27541                 skip "MDS needs to be newer than 2.13.56"
27542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27543
27544         for i in $(seq 0 $((MDSCOUNT - 1))); do
27545                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27546         done
27547
27548         local before=0
27549         local after=0
27550
27551         local tmp
27552
27553         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27554         for i in $(seq 0 $((MDSCOUNT - 1))); do
27555                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27556                         awk '/getattr/ { print $2 }')
27557                 before=$((before + tmp))
27558         done
27559         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27560         for i in $(seq 0 $((MDSCOUNT - 1))); do
27561                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27562                         awk '/getattr/ { print $2 }')
27563                 after=$((after + tmp))
27564         done
27565
27566         [ $before -eq $after ] || error "getattr count $before != $after"
27567 }
27568 run_test 803b "remote object can getattr from cache"
27569
27570 test_804() {
27571         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27572         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27573                 skip "MDS needs to be newer than 2.10.54"
27574         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27575
27576         mkdir -p $DIR/$tdir
27577         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27578                 error "Fail to create $DIR/$tdir/dir0"
27579
27580         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27581         local dev=$(mdsdevname 2)
27582
27583         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27584                 grep ${fid} || error "NOT found agent entry for dir0"
27585
27586         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27587                 error "Fail to create $DIR/$tdir/dir1"
27588
27589         touch $DIR/$tdir/dir1/foo0 ||
27590                 error "Fail to create $DIR/$tdir/dir1/foo0"
27591         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27592         local rc=0
27593
27594         for idx in $(seq $MDSCOUNT); do
27595                 dev=$(mdsdevname $idx)
27596                 do_facet mds${idx} \
27597                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27598                         grep ${fid} && rc=$idx
27599         done
27600
27601         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27602                 error "Fail to rename foo0 to foo1"
27603         if [ $rc -eq 0 ]; then
27604                 for idx in $(seq $MDSCOUNT); do
27605                         dev=$(mdsdevname $idx)
27606                         do_facet mds${idx} \
27607                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27608                         grep ${fid} && rc=$idx
27609                 done
27610         fi
27611
27612         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27613                 error "Fail to rename foo1 to foo2"
27614         if [ $rc -eq 0 ]; then
27615                 for idx in $(seq $MDSCOUNT); do
27616                         dev=$(mdsdevname $idx)
27617                         do_facet mds${idx} \
27618                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27619                         grep ${fid} && rc=$idx
27620                 done
27621         fi
27622
27623         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27624
27625         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27626                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27627         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27628                 error "Fail to rename foo2 to foo0"
27629         unlink $DIR/$tdir/dir1/foo0 ||
27630                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27631         rm -rf $DIR/$tdir/dir0 ||
27632                 error "Fail to rm $DIR/$tdir/dir0"
27633
27634         for idx in $(seq $MDSCOUNT); do
27635                 rc=0
27636
27637                 stop mds${idx}
27638                 dev=$(mdsdevname $idx)
27639                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27640                         rc=$?
27641                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27642                         error "mount mds$idx failed"
27643                 df $MOUNT > /dev/null 2>&1
27644
27645                 # e2fsck should not return error
27646                 [ $rc -eq 0 ] ||
27647                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27648         done
27649 }
27650 run_test 804 "verify agent entry for remote entry"
27651
27652 cleanup_805() {
27653         do_facet $SINGLEMDS zfs set quota=$old $fsset
27654         unlinkmany $DIR/$tdir/f- 1000000
27655         trap 0
27656 }
27657
27658 test_805() {
27659         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27660         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27661         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27662                 skip "netfree not implemented before 0.7"
27663         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27664                 skip "Need MDS version at least 2.10.57"
27665
27666         local fsset
27667         local freekb
27668         local usedkb
27669         local old
27670         local quota
27671         local pref="osd-zfs.$FSNAME-MDT0000."
27672
27673         # limit available space on MDS dataset to meet nospace issue
27674         # quickly. then ZFS 0.7.2 can use reserved space if asked
27675         # properly (using netfree flag in osd_declare_destroy()
27676         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27677         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27678                 gawk '{print $3}')
27679         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27680         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27681         let "usedkb=usedkb-freekb"
27682         let "freekb=freekb/2"
27683         if let "freekb > 5000"; then
27684                 let "freekb=5000"
27685         fi
27686         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27687         trap cleanup_805 EXIT
27688         mkdir_on_mdt0 $DIR/$tdir
27689         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27690                 error "Can't set PFL layout"
27691         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27692         rm -rf $DIR/$tdir || error "not able to remove"
27693         do_facet $SINGLEMDS zfs set quota=$old $fsset
27694         trap 0
27695 }
27696 run_test 805 "ZFS can remove from full fs"
27697
27698 # Size-on-MDS test
27699 check_lsom_data()
27700 {
27701         local file=$1
27702         local expect=$(stat -c %s $file)
27703
27704         check_lsom_size $1 $expect
27705
27706         local blocks=$($LFS getsom -b $file)
27707         expect=$(stat -c %b $file)
27708         [[ $blocks == $expect ]] ||
27709                 error "$file expected blocks: $expect, got: $blocks"
27710 }
27711
27712 check_lsom_size()
27713 {
27714         local size
27715         local expect=$2
27716
27717         cancel_lru_locks mdc
27718
27719         size=$($LFS getsom -s $1)
27720         [[ $size == $expect ]] ||
27721                 error "$file expected size: $expect, got: $size"
27722 }
27723
27724 test_806() {
27725         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27726                 skip "Need MDS version at least 2.11.52"
27727
27728         local bs=1048576
27729
27730         touch $DIR/$tfile || error "touch $tfile failed"
27731
27732         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27733         save_lustre_params client "llite.*.xattr_cache" > $save
27734         lctl set_param llite.*.xattr_cache=0
27735         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27736
27737         # single-threaded write
27738         echo "Test SOM for single-threaded write"
27739         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27740                 error "write $tfile failed"
27741         check_lsom_size $DIR/$tfile $bs
27742
27743         local num=32
27744         local size=$(($num * $bs))
27745         local offset=0
27746         local i
27747
27748         echo "Test SOM for single client multi-threaded($num) write"
27749         $TRUNCATE $DIR/$tfile 0
27750         for ((i = 0; i < $num; i++)); do
27751                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27752                 local pids[$i]=$!
27753                 offset=$((offset + $bs))
27754         done
27755         for (( i=0; i < $num; i++ )); do
27756                 wait ${pids[$i]}
27757         done
27758         check_lsom_size $DIR/$tfile $size
27759
27760         $TRUNCATE $DIR/$tfile 0
27761         for ((i = 0; i < $num; i++)); do
27762                 offset=$((offset - $bs))
27763                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27764                 local pids[$i]=$!
27765         done
27766         for (( i=0; i < $num; i++ )); do
27767                 wait ${pids[$i]}
27768         done
27769         check_lsom_size $DIR/$tfile $size
27770
27771         # multi-client writes
27772         num=$(get_node_count ${CLIENTS//,/ })
27773         size=$(($num * $bs))
27774         offset=0
27775         i=0
27776
27777         echo "Test SOM for multi-client ($num) writes"
27778         $TRUNCATE $DIR/$tfile 0
27779         for client in ${CLIENTS//,/ }; do
27780                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27781                 local pids[$i]=$!
27782                 i=$((i + 1))
27783                 offset=$((offset + $bs))
27784         done
27785         for (( i=0; i < $num; i++ )); do
27786                 wait ${pids[$i]}
27787         done
27788         check_lsom_size $DIR/$tfile $offset
27789
27790         i=0
27791         $TRUNCATE $DIR/$tfile 0
27792         for client in ${CLIENTS//,/ }; do
27793                 offset=$((offset - $bs))
27794                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27795                 local pids[$i]=$!
27796                 i=$((i + 1))
27797         done
27798         for (( i=0; i < $num; i++ )); do
27799                 wait ${pids[$i]}
27800         done
27801         check_lsom_size $DIR/$tfile $size
27802
27803         # verify truncate
27804         echo "Test SOM for truncate"
27805         $TRUNCATE $DIR/$tfile 1048576
27806         check_lsom_size $DIR/$tfile 1048576
27807         $TRUNCATE $DIR/$tfile 1234
27808         check_lsom_size $DIR/$tfile 1234
27809
27810         # verify SOM blocks count
27811         echo "Verify SOM block count"
27812         $TRUNCATE $DIR/$tfile 0
27813         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27814                 error "failed to write file $tfile"
27815         check_lsom_data $DIR/$tfile
27816 }
27817 run_test 806 "Verify Lazy Size on MDS"
27818
27819 test_807() {
27820         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27821         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27822                 skip "Need MDS version at least 2.11.52"
27823
27824         # Registration step
27825         changelog_register || error "changelog_register failed"
27826         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27827         changelog_users $SINGLEMDS | grep -q $cl_user ||
27828                 error "User $cl_user not found in changelog_users"
27829
27830         rm -rf $DIR/$tdir || error "rm $tdir failed"
27831         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27832         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27833         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27834         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27835                 error "truncate $tdir/trunc failed"
27836
27837         local bs=1048576
27838         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27839                 error "write $tfile failed"
27840
27841         # multi-client wirtes
27842         local num=$(get_node_count ${CLIENTS//,/ })
27843         local offset=0
27844         local i=0
27845
27846         echo "Test SOM for multi-client ($num) writes"
27847         touch $DIR/$tfile || error "touch $tfile failed"
27848         $TRUNCATE $DIR/$tfile 0
27849         for client in ${CLIENTS//,/ }; do
27850                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27851                 local pids[$i]=$!
27852                 i=$((i + 1))
27853                 offset=$((offset + $bs))
27854         done
27855         for (( i=0; i < $num; i++ )); do
27856                 wait ${pids[$i]}
27857         done
27858
27859         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27860         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27861         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27862         check_lsom_data $DIR/$tdir/trunc
27863         check_lsom_data $DIR/$tdir/single_dd
27864         check_lsom_data $DIR/$tfile
27865
27866         rm -rf $DIR/$tdir
27867         # Deregistration step
27868         changelog_deregister || error "changelog_deregister failed"
27869 }
27870 run_test 807 "verify LSOM syncing tool"
27871
27872 check_som_nologged()
27873 {
27874         local lines=$($LFS changelog $FSNAME-MDT0000 |
27875                 grep 'x=trusted.som' | wc -l)
27876         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27877 }
27878
27879 test_808() {
27880         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27881                 skip "Need MDS version at least 2.11.55"
27882
27883         # Registration step
27884         changelog_register || error "changelog_register failed"
27885
27886         touch $DIR/$tfile || error "touch $tfile failed"
27887         check_som_nologged
27888
27889         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27890                 error "write $tfile failed"
27891         check_som_nologged
27892
27893         $TRUNCATE $DIR/$tfile 1234
27894         check_som_nologged
27895
27896         $TRUNCATE $DIR/$tfile 1048576
27897         check_som_nologged
27898
27899         # Deregistration step
27900         changelog_deregister || error "changelog_deregister failed"
27901 }
27902 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27903
27904 check_som_nodata()
27905 {
27906         $LFS getsom $1
27907         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27908 }
27909
27910 test_809() {
27911         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27912                 skip "Need MDS version at least 2.11.56"
27913
27914         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27915                 error "failed to create DoM-only file $DIR/$tfile"
27916         touch $DIR/$tfile || error "touch $tfile failed"
27917         check_som_nodata $DIR/$tfile
27918
27919         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27920                 error "write $tfile failed"
27921         check_som_nodata $DIR/$tfile
27922
27923         $TRUNCATE $DIR/$tfile 1234
27924         check_som_nodata $DIR/$tfile
27925
27926         $TRUNCATE $DIR/$tfile 4097
27927         check_som_nodata $DIR/$file
27928 }
27929 run_test 809 "Verify no SOM xattr store for DoM-only files"
27930
27931 test_810() {
27932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27933         $GSS && skip_env "could not run with gss"
27934         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27935                 skip "OST < 2.12.58 doesn't align checksum"
27936
27937         set_checksums 1
27938         stack_trap "set_checksums $ORIG_CSUM" EXIT
27939         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27940
27941         local csum
27942         local before
27943         local after
27944         for csum in $CKSUM_TYPES; do
27945                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27946                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27947                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27948                         eval set -- $i
27949                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27950                         before=$(md5sum $DIR/$tfile)
27951                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27952                         after=$(md5sum $DIR/$tfile)
27953                         [ "$before" == "$after" ] ||
27954                                 error "$csum: $before != $after bs=$1 seek=$2"
27955                 done
27956         done
27957 }
27958 run_test 810 "partial page writes on ZFS (LU-11663)"
27959
27960 test_812a() {
27961         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27962                 skip "OST < 2.12.51 doesn't support this fail_loc"
27963
27964         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27965         # ensure ost1 is connected
27966         stat $DIR/$tfile >/dev/null || error "can't stat"
27967         wait_osc_import_state client ost1 FULL
27968         # no locks, no reqs to let the connection idle
27969         cancel_lru_locks osc
27970
27971         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27972 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27973         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27974         wait_osc_import_state client ost1 CONNECTING
27975         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27976
27977         stat $DIR/$tfile >/dev/null || error "can't stat file"
27978 }
27979 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27980
27981 test_812b() { # LU-12378
27982         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27983                 skip "OST < 2.12.51 doesn't support this fail_loc"
27984
27985         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27986         # ensure ost1 is connected
27987         stat $DIR/$tfile >/dev/null || error "can't stat"
27988         wait_osc_import_state client ost1 FULL
27989         # no locks, no reqs to let the connection idle
27990         cancel_lru_locks osc
27991
27992         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27993 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27994         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27995         wait_osc_import_state client ost1 CONNECTING
27996         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27997
27998         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27999         wait_osc_import_state client ost1 IDLE
28000 }
28001 run_test 812b "do not drop no resend request for idle connect"
28002
28003 test_812c() {
28004         local old
28005
28006         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28007
28008         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28009         $LFS getstripe $DIR/$tfile
28010         $LCTL set_param osc.*.idle_timeout=10
28011         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28012         # ensure ost1 is connected
28013         stat $DIR/$tfile >/dev/null || error "can't stat"
28014         wait_osc_import_state client ost1 FULL
28015         # no locks, no reqs to let the connection idle
28016         cancel_lru_locks osc
28017
28018 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28019         $LCTL set_param fail_loc=0x80000533
28020         sleep 15
28021         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28022 }
28023 run_test 812c "idle import vs lock enqueue race"
28024
28025 test_813() {
28026         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28027         [ -z "$file_heat_sav" ] && skip "no file heat support"
28028
28029         local readsample
28030         local writesample
28031         local readbyte
28032         local writebyte
28033         local readsample1
28034         local writesample1
28035         local readbyte1
28036         local writebyte1
28037
28038         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28039         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28040
28041         $LCTL set_param -n llite.*.file_heat=1
28042         echo "Turn on file heat"
28043         echo "Period second: $period_second, Decay percentage: $decay_pct"
28044
28045         echo "QQQQ" > $DIR/$tfile
28046         echo "QQQQ" > $DIR/$tfile
28047         echo "QQQQ" > $DIR/$tfile
28048         cat $DIR/$tfile > /dev/null
28049         cat $DIR/$tfile > /dev/null
28050         cat $DIR/$tfile > /dev/null
28051         cat $DIR/$tfile > /dev/null
28052
28053         local out=$($LFS heat_get $DIR/$tfile)
28054
28055         $LFS heat_get $DIR/$tfile
28056         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28057         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28058         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28059         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28060
28061         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28062         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28063         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28064         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28065
28066         sleep $((period_second + 3))
28067         echo "Sleep $((period_second + 3)) seconds..."
28068         # The recursion formula to calculate the heat of the file f is as
28069         # follow:
28070         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28071         # Where Hi is the heat value in the period between time points i*I and
28072         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28073         # to the weight of Ci.
28074         out=$($LFS heat_get $DIR/$tfile)
28075         $LFS heat_get $DIR/$tfile
28076         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28077         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28078         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28079         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28080
28081         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28082                 error "read sample ($readsample) is wrong"
28083         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28084                 error "write sample ($writesample) is wrong"
28085         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28086                 error "read bytes ($readbyte) is wrong"
28087         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28088                 error "write bytes ($writebyte) is wrong"
28089
28090         echo "QQQQ" > $DIR/$tfile
28091         echo "QQQQ" > $DIR/$tfile
28092         echo "QQQQ" > $DIR/$tfile
28093         cat $DIR/$tfile > /dev/null
28094         cat $DIR/$tfile > /dev/null
28095         cat $DIR/$tfile > /dev/null
28096         cat $DIR/$tfile > /dev/null
28097
28098         sleep $((period_second + 3))
28099         echo "Sleep $((period_second + 3)) seconds..."
28100
28101         out=$($LFS heat_get $DIR/$tfile)
28102         $LFS heat_get $DIR/$tfile
28103         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28104         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28105         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28106         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28107
28108         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28109                 4 * $decay_pct) / 100") -eq 1 ] ||
28110                 error "read sample ($readsample1) is wrong"
28111         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28112                 3 * $decay_pct) / 100") -eq 1 ] ||
28113                 error "write sample ($writesample1) is wrong"
28114         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28115                 20 * $decay_pct) / 100") -eq 1 ] ||
28116                 error "read bytes ($readbyte1) is wrong"
28117         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28118                 15 * $decay_pct) / 100") -eq 1 ] ||
28119                 error "write bytes ($writebyte1) is wrong"
28120
28121         echo "Turn off file heat for the file $DIR/$tfile"
28122         $LFS heat_set -o $DIR/$tfile
28123
28124         echo "QQQQ" > $DIR/$tfile
28125         echo "QQQQ" > $DIR/$tfile
28126         echo "QQQQ" > $DIR/$tfile
28127         cat $DIR/$tfile > /dev/null
28128         cat $DIR/$tfile > /dev/null
28129         cat $DIR/$tfile > /dev/null
28130         cat $DIR/$tfile > /dev/null
28131
28132         out=$($LFS heat_get $DIR/$tfile)
28133         $LFS heat_get $DIR/$tfile
28134         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28135         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28136         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28137         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28138
28139         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28140         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28141         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28142         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28143
28144         echo "Trun on file heat for the file $DIR/$tfile"
28145         $LFS heat_set -O $DIR/$tfile
28146
28147         echo "QQQQ" > $DIR/$tfile
28148         echo "QQQQ" > $DIR/$tfile
28149         echo "QQQQ" > $DIR/$tfile
28150         cat $DIR/$tfile > /dev/null
28151         cat $DIR/$tfile > /dev/null
28152         cat $DIR/$tfile > /dev/null
28153         cat $DIR/$tfile > /dev/null
28154
28155         out=$($LFS heat_get $DIR/$tfile)
28156         $LFS heat_get $DIR/$tfile
28157         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28158         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28159         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28160         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28161
28162         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28163         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28164         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28165         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28166
28167         $LFS heat_set -c $DIR/$tfile
28168         $LCTL set_param -n llite.*.file_heat=0
28169         echo "Turn off file heat support for the Lustre filesystem"
28170
28171         echo "QQQQ" > $DIR/$tfile
28172         echo "QQQQ" > $DIR/$tfile
28173         echo "QQQQ" > $DIR/$tfile
28174         cat $DIR/$tfile > /dev/null
28175         cat $DIR/$tfile > /dev/null
28176         cat $DIR/$tfile > /dev/null
28177         cat $DIR/$tfile > /dev/null
28178
28179         out=$($LFS heat_get $DIR/$tfile)
28180         $LFS heat_get $DIR/$tfile
28181         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28182         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28183         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28184         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28185
28186         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28187         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28188         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28189         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28190
28191         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28192         rm -f $DIR/$tfile
28193 }
28194 run_test 813 "File heat verfication"
28195
28196 test_814()
28197 {
28198         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28199         echo -n y >> $DIR/$tfile
28200         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28201         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28202 }
28203 run_test 814 "sparse cp works as expected (LU-12361)"
28204
28205 test_815()
28206 {
28207         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28208         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28209 }
28210 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28211
28212 test_816() {
28213         local ost1_imp=$(get_osc_import_name client ost1)
28214         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28215                          cut -d'.' -f2)
28216
28217         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28218         # ensure ost1 is connected
28219
28220         stat $DIR/$tfile >/dev/null || error "can't stat"
28221         wait_osc_import_state client ost1 FULL
28222         # no locks, no reqs to let the connection idle
28223         cancel_lru_locks osc
28224         lru_resize_disable osc
28225         local before
28226         local now
28227         before=$($LCTL get_param -n \
28228                  ldlm.namespaces.$imp_name.lru_size)
28229
28230         wait_osc_import_state client ost1 IDLE
28231         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28232         now=$($LCTL get_param -n \
28233               ldlm.namespaces.$imp_name.lru_size)
28234         [ $before == $now ] || error "lru_size changed $before != $now"
28235 }
28236 run_test 816 "do not reset lru_resize on idle reconnect"
28237
28238 cleanup_817() {
28239         umount $tmpdir
28240         exportfs -u localhost:$DIR/nfsexp
28241         rm -rf $DIR/nfsexp
28242 }
28243
28244 test_817() {
28245         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28246
28247         mkdir -p $DIR/nfsexp
28248         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28249                 error "failed to export nfs"
28250
28251         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28252         stack_trap cleanup_817 EXIT
28253
28254         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28255                 error "failed to mount nfs to $tmpdir"
28256
28257         cp /bin/true $tmpdir
28258         $DIR/nfsexp/true || error "failed to execute 'true' command"
28259 }
28260 run_test 817 "nfsd won't cache write lock for exec file"
28261
28262 test_818() {
28263         test_mkdir -i0 -c1 $DIR/$tdir
28264         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28265         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28266         stop $SINGLEMDS
28267
28268         # restore osp-syn threads
28269         stack_trap "fail $SINGLEMDS"
28270
28271         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28272         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28273         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28274                 error "start $SINGLEMDS failed"
28275         rm -rf $DIR/$tdir
28276
28277         local testid=$(echo $TESTNAME | tr '_' ' ')
28278
28279         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28280                 grep "run LFSCK" || error "run LFSCK is not suggested"
28281 }
28282 run_test 818 "unlink with failed llog"
28283
28284 test_819a() {
28285         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28286         cancel_lru_locks osc
28287         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28288         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28289         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28290         rm -f $TDIR/$tfile
28291 }
28292 run_test 819a "too big niobuf in read"
28293
28294 test_819b() {
28295         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28296         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28297         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28298         cancel_lru_locks osc
28299         sleep 1
28300         rm -f $TDIR/$tfile
28301 }
28302 run_test 819b "too big niobuf in write"
28303
28304
28305 function test_820_start_ost() {
28306         sleep 5
28307
28308         for num in $(seq $OSTCOUNT); do
28309                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28310         done
28311 }
28312
28313 test_820() {
28314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28315
28316         mkdir $DIR/$tdir
28317         umount_client $MOUNT || error "umount failed"
28318         for num in $(seq $OSTCOUNT); do
28319                 stop ost$num
28320         done
28321
28322         # mount client with no active OSTs
28323         # so that the client can't initialize max LOV EA size
28324         # from OSC notifications
28325         mount_client $MOUNT || error "mount failed"
28326         # delay OST starting to keep this 0 max EA size for a while
28327         test_820_start_ost &
28328
28329         # create a directory on MDS2
28330         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28331                 error "Failed to create directory"
28332         # open intent should update default EA size
28333         # see mdc_update_max_ea_from_body()
28334         # notice this is the very first RPC to MDS2
28335         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28336         ret=$?
28337         echo $out
28338         # With SSK, this situation can lead to -EPERM being returned.
28339         # In that case, simply retry.
28340         if [ $ret -ne 0 ] && $SHARED_KEY; then
28341                 if echo "$out" | grep -q "not permitted"; then
28342                         cp /etc/services $DIR/$tdir/mds2
28343                         ret=$?
28344                 fi
28345         fi
28346         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28347 }
28348 run_test 820 "update max EA from open intent"
28349
28350 test_823() {
28351         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28352         local OST_MAX_PRECREATE=20000
28353
28354         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28355                 skip "Need MDS version at least 2.14.56"
28356
28357         save_lustre_params mds1 \
28358                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28359         do_facet $SINGLEMDS "$LCTL set_param -n \
28360                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28361         do_facet $SINGLEMDS "$LCTL set_param -n \
28362                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28363
28364         stack_trap "restore_lustre_params < $p; rm $p"
28365
28366         do_facet $SINGLEMDS "$LCTL set_param -n \
28367                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28368
28369         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28370                       osp.$FSNAME-OST0000*MDT0000.create_count")
28371         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28372                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28373         local expect_count=$(((($max/2)/256) * 256))
28374
28375         log "setting create_count to 100200:"
28376         log " -result- count: $count with max: $max, expecting: $expect_count"
28377
28378         [[ $count -eq expect_count ]] ||
28379                 error "Create count not set to max precreate."
28380 }
28381 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28382
28383 test_831() {
28384         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28385                 skip "Need MDS version 2.14.56"
28386
28387         local sync_changes=$(do_facet $SINGLEMDS \
28388                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28389
28390         [ "$sync_changes" -gt 100 ] &&
28391                 skip "Sync changes $sync_changes > 100 already"
28392
28393         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28394
28395         $LFS mkdir -i 0 $DIR/$tdir
28396         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28397
28398         save_lustre_params mds1 \
28399                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28400         save_lustre_params mds1 \
28401                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28402
28403         do_facet mds1 "$LCTL set_param -n \
28404                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28405                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28406         stack_trap "restore_lustre_params < $p" EXIT
28407
28408         createmany -o $DIR/$tdir/f- 1000
28409         unlinkmany $DIR/$tdir/f- 1000 &
28410         local UNLINK_PID=$!
28411
28412         while sleep 1; do
28413                 sync_changes=$(do_facet mds1 \
28414                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28415                 # the check in the code is racy, fail the test
28416                 # if the value above the limit by 10.
28417                 [ $sync_changes -gt 110 ] && {
28418                         kill -2 $UNLINK_PID
28419                         wait
28420                         error "osp changes throttling failed, $sync_changes>110"
28421                 }
28422                 kill -0 $UNLINK_PID 2> /dev/null || break
28423         done
28424         wait
28425 }
28426 run_test 831 "throttling unlink/setattr queuing on OSP"
28427
28428 #
28429 # tests that do cleanup/setup should be run at the end
28430 #
28431
28432 test_900() {
28433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28434         local ls
28435
28436         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28437         $LCTL set_param fail_loc=0x903
28438
28439         cancel_lru_locks MGC
28440
28441         FAIL_ON_ERROR=true cleanup
28442         FAIL_ON_ERROR=true setup
28443 }
28444 run_test 900 "umount should not race with any mgc requeue thread"
28445
28446 # LUS-6253/LU-11185
28447 test_901() {
28448         local old
28449         local count
28450         local oldc
28451         local newc
28452         local olds
28453         local news
28454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28455
28456         # some get_param have a bug to handle dot in param name
28457         cancel_lru_locks MGC
28458         old=$(mount -t lustre | wc -l)
28459         # 1 config+sptlrpc
28460         # 2 params
28461         # 3 nodemap
28462         # 4 IR
28463         old=$((old * 4))
28464         oldc=0
28465         count=0
28466         while [ $old -ne $oldc ]; do
28467                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28468                 sleep 1
28469                 ((count++))
28470                 if [ $count -ge $TIMEOUT ]; then
28471                         error "too large timeout"
28472                 fi
28473         done
28474         umount_client $MOUNT || error "umount failed"
28475         mount_client $MOUNT || error "mount failed"
28476         cancel_lru_locks MGC
28477         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28478
28479         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28480
28481         return 0
28482 }
28483 run_test 901 "don't leak a mgc lock on client umount"
28484
28485 # LU-13377
28486 test_902() {
28487         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28488                 skip "client does not have LU-13377 fix"
28489         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28490         $LCTL set_param fail_loc=0x1415
28491         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28492         cancel_lru_locks osc
28493         rm -f $DIR/$tfile
28494 }
28495 run_test 902 "test short write doesn't hang lustre"
28496
28497 # LU-14711
28498 test_903() {
28499         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28500         echo "blah" > $DIR/${tfile}-2
28501         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28502         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28503         $LCTL set_param fail_loc=0x417 fail_val=20
28504
28505         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28506         sleep 1 # To start the destroy
28507         wait_destroy_complete 150 || error "Destroy taking too long"
28508         cat $DIR/$tfile > /dev/null || error "Evicted"
28509 }
28510 run_test 903 "Test long page discard does not cause evictions"
28511
28512 test_904() {
28513         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28514         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28515                 grep -q project || skip "skip project quota not supported"
28516
28517         local testfile="$DIR/$tdir/$tfile"
28518         local xattr="trusted.projid"
28519         local projid
28520         local mdts=$(comma_list $(mdts_nodes))
28521         local saved=$(do_facet mds1 $LCTL get_param -n \
28522                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28523
28524         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28525         stack_trap "do_nodes $mdts $LCTL set_param \
28526                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28527
28528         mkdir -p $DIR/$tdir
28529         touch $testfile
28530         #hide projid xattr on server
28531         $LFS project -p 1 $testfile ||
28532                 error "set $testfile project id failed"
28533         getfattr -m - $testfile | grep $xattr &&
28534                 error "do not show trusted.projid when disabled on server"
28535         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28536         #should be hidden when projid is 0
28537         $LFS project -p 0 $testfile ||
28538                 error "set $testfile project id failed"
28539         getfattr -m - $testfile | grep $xattr &&
28540                 error "do not show trusted.projid with project ID 0"
28541
28542         #still can getxattr explicitly
28543         projid=$(getfattr -n $xattr $testfile |
28544                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28545         [ $projid == "0" ] ||
28546                 error "projid expected 0 not $projid"
28547
28548         #set the projid via setxattr
28549         setfattr -n $xattr -v "1000" $testfile ||
28550                 error "setattr failed with $?"
28551         projid=($($LFS project $testfile))
28552         [ ${projid[0]} == "1000" ] ||
28553                 error "projid expected 1000 not $projid"
28554
28555         #check the new projid via getxattr
28556         $LFS project -p 1001 $testfile ||
28557                 error "set $testfile project id failed"
28558         getfattr -m - $testfile | grep $xattr ||
28559                 error "should show trusted.projid when project ID != 0"
28560         projid=$(getfattr -n $xattr $testfile |
28561                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28562         [ $projid == "1001" ] ||
28563                 error "projid expected 1001 not $projid"
28564
28565         #try to set invalid projid
28566         setfattr -n $xattr -v "4294967295" $testfile &&
28567                 error "set invalid projid should fail"
28568
28569         #remove the xattr means setting projid to 0
28570         setfattr -x $xattr $testfile ||
28571                 error "setfattr failed with $?"
28572         projid=($($LFS project $testfile))
28573         [ ${projid[0]} == "0" ] ||
28574                 error "projid expected 0 not $projid"
28575
28576         #should be hidden when parent has inherit flag and same projid
28577         $LFS project -srp 1002 $DIR/$tdir ||
28578                 error "set $tdir project id failed"
28579         getfattr -m - $testfile | grep $xattr &&
28580                 error "do not show trusted.projid with inherit flag"
28581
28582         #still can getxattr explicitly
28583         projid=$(getfattr -n $xattr $testfile |
28584                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28585         [ $projid == "1002" ] ||
28586                 error "projid expected 1002 not $projid"
28587 }
28588 run_test 904 "virtual project ID xattr"
28589
28590 # LU-8582
28591 test_905() {
28592         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28593                 skip "lustre < 2.8.54 does not support ladvise"
28594
28595         remote_ost_nodsh && skip "remote OST with nodsh"
28596         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28597
28598         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28599
28600         #define OBD_FAIL_OST_OPCODE 0x253
28601         # OST_LADVISE = 21
28602         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28603         $LFS ladvise -a willread $DIR/$tfile &&
28604                 error "unexpected success of ladvise with fault injection"
28605         $LFS ladvise -a willread $DIR/$tfile |&
28606                 grep -q "Operation not supported"
28607         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28608 }
28609 run_test 905 "bad or new opcode should not stuck client"
28610
28611 complete $SECONDS
28612 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28613 check_and_cleanup_lustre
28614 if [ "$I_MOUNTED" != "yes" ]; then
28615         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28616 fi
28617 exit_status