Whamcloud - gitweb
LU-14139 llite: simplify callback handling for async getattr
[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_123d() {
13181         local num=100
13182         local swrong
13183         local ewrong
13184
13185         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13186         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13187                 error "setdirstripe $DIR/$tdir failed"
13188         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13189         remount_client $MOUNT
13190         $LCTL get_param llite.*.statahead_max
13191         swrong=$(lctl get_param -n llite.*.statahead_stats |
13192                 grep "statahead wrong:" | awk '{print $3}')
13193         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13194         $LCTL get_param -n llite.*.statahead_stats
13195         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13196                 grep "statahead wrong:" | awk '{print $3}')
13197         [[ $swrong -eq $ewrong ]] ||
13198                 log "statahead was stopped, maybe too many locks held!"
13199 }
13200 run_test 123d "Statahead on striped directories works correctly"
13201
13202 test_124a() {
13203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13204         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13205                 skip_env "no lru resize on server"
13206
13207         local NR=2000
13208
13209         test_mkdir $DIR/$tdir
13210
13211         log "create $NR files at $DIR/$tdir"
13212         createmany -o $DIR/$tdir/f $NR ||
13213                 error "failed to create $NR files in $DIR/$tdir"
13214
13215         cancel_lru_locks mdc
13216         ls -l $DIR/$tdir > /dev/null
13217
13218         local NSDIR=""
13219         local LRU_SIZE=0
13220         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13221                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13222                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13223                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13224                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13225                         log "NSDIR=$NSDIR"
13226                         log "NS=$(basename $NSDIR)"
13227                         break
13228                 fi
13229         done
13230
13231         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13232                 skip "Not enough cached locks created!"
13233         fi
13234         log "LRU=$LRU_SIZE"
13235
13236         local SLEEP=30
13237
13238         # We know that lru resize allows one client to hold $LIMIT locks
13239         # for 10h. After that locks begin to be killed by client.
13240         local MAX_HRS=10
13241         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13242         log "LIMIT=$LIMIT"
13243         if [ $LIMIT -lt $LRU_SIZE ]; then
13244                 skip "Limit is too small $LIMIT"
13245         fi
13246
13247         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13248         # killing locks. Some time was spent for creating locks. This means
13249         # that up to the moment of sleep finish we must have killed some of
13250         # them (10-100 locks). This depends on how fast ther were created.
13251         # Many of them were touched in almost the same moment and thus will
13252         # be killed in groups.
13253         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13254
13255         # Use $LRU_SIZE_B here to take into account real number of locks
13256         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13257         local LRU_SIZE_B=$LRU_SIZE
13258         log "LVF=$LVF"
13259         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13260         log "OLD_LVF=$OLD_LVF"
13261         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13262
13263         # Let's make sure that we really have some margin. Client checks
13264         # cached locks every 10 sec.
13265         SLEEP=$((SLEEP+20))
13266         log "Sleep ${SLEEP} sec"
13267         local SEC=0
13268         while ((SEC<$SLEEP)); do
13269                 echo -n "..."
13270                 sleep 5
13271                 SEC=$((SEC+5))
13272                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13273                 echo -n "$LRU_SIZE"
13274         done
13275         echo ""
13276         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13277         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13278
13279         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13280                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13281                 unlinkmany $DIR/$tdir/f $NR
13282                 return
13283         }
13284
13285         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13286         log "unlink $NR files at $DIR/$tdir"
13287         unlinkmany $DIR/$tdir/f $NR
13288 }
13289 run_test 124a "lru resize ======================================="
13290
13291 get_max_pool_limit()
13292 {
13293         local limit=$($LCTL get_param \
13294                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13295         local max=0
13296         for l in $limit; do
13297                 if [[ $l -gt $max ]]; then
13298                         max=$l
13299                 fi
13300         done
13301         echo $max
13302 }
13303
13304 test_124b() {
13305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13306         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13307                 skip_env "no lru resize on server"
13308
13309         LIMIT=$(get_max_pool_limit)
13310
13311         NR=$(($(default_lru_size)*20))
13312         if [[ $NR -gt $LIMIT ]]; then
13313                 log "Limit lock number by $LIMIT locks"
13314                 NR=$LIMIT
13315         fi
13316
13317         IFree=$(mdsrate_inodes_available)
13318         if [ $IFree -lt $NR ]; then
13319                 log "Limit lock number by $IFree inodes"
13320                 NR=$IFree
13321         fi
13322
13323         lru_resize_disable mdc
13324         test_mkdir -p $DIR/$tdir/disable_lru_resize
13325
13326         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13327         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13328         cancel_lru_locks mdc
13329         stime=`date +%s`
13330         PID=""
13331         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13332         PID="$PID $!"
13333         sleep 2
13334         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13335         PID="$PID $!"
13336         sleep 2
13337         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13338         PID="$PID $!"
13339         wait $PID
13340         etime=`date +%s`
13341         nolruresize_delta=$((etime-stime))
13342         log "ls -la time: $nolruresize_delta seconds"
13343         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13344         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13345
13346         lru_resize_enable mdc
13347         test_mkdir -p $DIR/$tdir/enable_lru_resize
13348
13349         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13350         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13351         cancel_lru_locks mdc
13352         stime=`date +%s`
13353         PID=""
13354         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13355         PID="$PID $!"
13356         sleep 2
13357         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13358         PID="$PID $!"
13359         sleep 2
13360         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13361         PID="$PID $!"
13362         wait $PID
13363         etime=`date +%s`
13364         lruresize_delta=$((etime-stime))
13365         log "ls -la time: $lruresize_delta seconds"
13366         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13367
13368         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13369                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13370         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13371                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13372         else
13373                 log "lru resize performs the same with no lru resize"
13374         fi
13375         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13376 }
13377 run_test 124b "lru resize (performance test) ======================="
13378
13379 test_124c() {
13380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13381         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13382                 skip_env "no lru resize on server"
13383
13384         # cache ununsed locks on client
13385         local nr=100
13386         cancel_lru_locks mdc
13387         test_mkdir $DIR/$tdir
13388         createmany -o $DIR/$tdir/f $nr ||
13389                 error "failed to create $nr files in $DIR/$tdir"
13390         ls -l $DIR/$tdir > /dev/null
13391
13392         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13393         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13394         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13395         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13396         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13397
13398         # set lru_max_age to 1 sec
13399         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13400         echo "sleep $((recalc_p * 2)) seconds..."
13401         sleep $((recalc_p * 2))
13402
13403         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13404         # restore lru_max_age
13405         $LCTL set_param -n $nsdir.lru_max_age $max_age
13406         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13407         unlinkmany $DIR/$tdir/f $nr
13408 }
13409 run_test 124c "LRUR cancel very aged locks"
13410
13411 test_124d() {
13412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13413         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13414                 skip_env "no lru resize on server"
13415
13416         # cache ununsed locks on client
13417         local nr=100
13418
13419         lru_resize_disable mdc
13420         stack_trap "lru_resize_enable mdc" EXIT
13421
13422         cancel_lru_locks mdc
13423
13424         # asynchronous object destroy at MDT could cause bl ast to client
13425         test_mkdir $DIR/$tdir
13426         createmany -o $DIR/$tdir/f $nr ||
13427                 error "failed to create $nr files in $DIR/$tdir"
13428         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13429
13430         ls -l $DIR/$tdir > /dev/null
13431
13432         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13433         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13434         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13435         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13436
13437         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13438
13439         # set lru_max_age to 1 sec
13440         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13441         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13442
13443         echo "sleep $((recalc_p * 2)) seconds..."
13444         sleep $((recalc_p * 2))
13445
13446         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13447
13448         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13449 }
13450 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13451
13452 test_125() { # 13358
13453         $LCTL get_param -n llite.*.client_type | grep -q local ||
13454                 skip "must run as local client"
13455         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13456                 skip_env "must have acl enabled"
13457         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13458
13459         test_mkdir $DIR/$tdir
13460         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13461         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13462         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13463 }
13464 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13465
13466 test_126() { # bug 12829/13455
13467         $GSS && skip_env "must run as gss disabled"
13468         $LCTL get_param -n llite.*.client_type | grep -q local ||
13469                 skip "must run as local client"
13470         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13471
13472         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13473         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13474         rm -f $DIR/$tfile
13475         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13476 }
13477 run_test 126 "check that the fsgid provided by the client is taken into account"
13478
13479 test_127a() { # bug 15521
13480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13481         local name count samp unit min max sum sumsq
13482
13483         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13484         echo "stats before reset"
13485         $LCTL get_param osc.*.stats
13486         $LCTL set_param osc.*.stats=0
13487         local fsize=$((2048 * 1024))
13488
13489         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13490         cancel_lru_locks osc
13491         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13492
13493         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13494         stack_trap "rm -f $TMP/$tfile.tmp"
13495         while read name count samp unit min max sum sumsq; do
13496                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13497                 [ ! $min ] && error "Missing min value for $name proc entry"
13498                 eval $name=$count || error "Wrong proc format"
13499
13500                 case $name in
13501                 read_bytes|write_bytes)
13502                         [[ "$unit" =~ "bytes" ]] ||
13503                                 error "unit is not 'bytes': $unit"
13504                         (( $min >= 4096 )) || error "min is too small: $min"
13505                         (( $min <= $fsize )) || error "min is too big: $min"
13506                         (( $max >= 4096 )) || error "max is too small: $max"
13507                         (( $max <= $fsize )) || error "max is too big: $max"
13508                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13509                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13510                                 error "sumsquare is too small: $sumsq"
13511                         (( $sumsq <= $fsize * $fsize )) ||
13512                                 error "sumsquare is too big: $sumsq"
13513                         ;;
13514                 ost_read|ost_write)
13515                         [[ "$unit" =~ "usec" ]] ||
13516                                 error "unit is not 'usec': $unit"
13517                         ;;
13518                 *)      ;;
13519                 esac
13520         done < $DIR/$tfile.tmp
13521
13522         #check that we actually got some stats
13523         [ "$read_bytes" ] || error "Missing read_bytes stats"
13524         [ "$write_bytes" ] || error "Missing write_bytes stats"
13525         [ "$read_bytes" != 0 ] || error "no read done"
13526         [ "$write_bytes" != 0 ] || error "no write done"
13527 }
13528 run_test 127a "verify the client stats are sane"
13529
13530 test_127b() { # bug LU-333
13531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13532         local name count samp unit min max sum sumsq
13533
13534         echo "stats before reset"
13535         $LCTL get_param llite.*.stats
13536         $LCTL set_param llite.*.stats=0
13537
13538         # perform 2 reads and writes so MAX is different from SUM.
13539         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13540         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13541         cancel_lru_locks osc
13542         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13543         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13544
13545         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13546         stack_trap "rm -f $TMP/$tfile.tmp"
13547         while read name count samp unit min max sum sumsq; do
13548                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13549                 eval $name=$count || error "Wrong proc format"
13550
13551                 case $name in
13552                 read_bytes|write_bytes)
13553                         [[ "$unit" =~ "bytes" ]] ||
13554                                 error "unit is not 'bytes': $unit"
13555                         (( $count == 2 )) || error "count is not 2: $count"
13556                         (( $min == $PAGE_SIZE )) ||
13557                                 error "min is not $PAGE_SIZE: $min"
13558                         (( $max == $PAGE_SIZE )) ||
13559                                 error "max is not $PAGE_SIZE: $max"
13560                         (( $sum == $PAGE_SIZE * 2 )) ||
13561                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13562                         ;;
13563                 read|write)
13564                         [[ "$unit" =~ "usec" ]] ||
13565                                 error "unit is not 'usec': $unit"
13566                         ;;
13567                 *)      ;;
13568                 esac
13569         done < $TMP/$tfile.tmp
13570
13571         #check that we actually got some stats
13572         [ "$read_bytes" ] || error "Missing read_bytes stats"
13573         [ "$write_bytes" ] || error "Missing write_bytes stats"
13574         [ "$read_bytes" != 0 ] || error "no read done"
13575         [ "$write_bytes" != 0 ] || error "no write done"
13576 }
13577 run_test 127b "verify the llite client stats are sane"
13578
13579 test_127c() { # LU-12394
13580         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13581         local size
13582         local bsize
13583         local reads
13584         local writes
13585         local count
13586
13587         $LCTL set_param llite.*.extents_stats=1
13588         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13589
13590         # Use two stripes so there is enough space in default config
13591         $LFS setstripe -c 2 $DIR/$tfile
13592
13593         # Extent stats start at 0-4K and go in power of two buckets
13594         # LL_HIST_START = 12 --> 2^12 = 4K
13595         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13596         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13597         # small configs
13598         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13599                 do
13600                 # Write and read, 2x each, second time at a non-zero offset
13601                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13602                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13603                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13604                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13605                 rm -f $DIR/$tfile
13606         done
13607
13608         $LCTL get_param llite.*.extents_stats
13609
13610         count=2
13611         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13612                 do
13613                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13614                                 grep -m 1 $bsize)
13615                 reads=$(echo $bucket | awk '{print $5}')
13616                 writes=$(echo $bucket | awk '{print $9}')
13617                 [ "$reads" -eq $count ] ||
13618                         error "$reads reads in < $bsize bucket, expect $count"
13619                 [ "$writes" -eq $count ] ||
13620                         error "$writes writes in < $bsize bucket, expect $count"
13621         done
13622
13623         # Test mmap write and read
13624         $LCTL set_param llite.*.extents_stats=c
13625         size=512
13626         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13627         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13628         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13629
13630         $LCTL get_param llite.*.extents_stats
13631
13632         count=$(((size*1024) / PAGE_SIZE))
13633
13634         bsize=$((2 * PAGE_SIZE / 1024))K
13635
13636         bucket=$($LCTL get_param -n llite.*.extents_stats |
13637                         grep -m 1 $bsize)
13638         reads=$(echo $bucket | awk '{print $5}')
13639         writes=$(echo $bucket | awk '{print $9}')
13640         # mmap writes fault in the page first, creating an additonal read
13641         [ "$reads" -eq $((2 * count)) ] ||
13642                 error "$reads reads in < $bsize bucket, expect $count"
13643         [ "$writes" -eq $count ] ||
13644                 error "$writes writes in < $bsize bucket, expect $count"
13645 }
13646 run_test 127c "test llite extent stats with regular & mmap i/o"
13647
13648 test_128() { # bug 15212
13649         touch $DIR/$tfile
13650         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13651                 find $DIR/$tfile
13652                 find $DIR/$tfile
13653         EOF
13654
13655         result=$(grep error $TMP/$tfile.log)
13656         rm -f $DIR/$tfile $TMP/$tfile.log
13657         [ -z "$result" ] ||
13658                 error "consecutive find's under interactive lfs failed"
13659 }
13660 run_test 128 "interactive lfs for 2 consecutive find's"
13661
13662 set_dir_limits () {
13663         local mntdev
13664         local canondev
13665         local node
13666
13667         local ldproc=/proc/fs/ldiskfs
13668         local facets=$(get_facets MDS)
13669
13670         for facet in ${facets//,/ }; do
13671                 canondev=$(ldiskfs_canon \
13672                            *.$(convert_facet2label $facet).mntdev $facet)
13673                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13674                         ldproc=/sys/fs/ldiskfs
13675                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13676                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13677         done
13678 }
13679
13680 check_mds_dmesg() {
13681         local facets=$(get_facets MDS)
13682         for facet in ${facets//,/ }; do
13683                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13684         done
13685         return 1
13686 }
13687
13688 test_129() {
13689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13690         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13691                 skip "Need MDS version with at least 2.5.56"
13692         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13693                 skip_env "ldiskfs only test"
13694         fi
13695         remote_mds_nodsh && skip "remote MDS with nodsh"
13696
13697         local ENOSPC=28
13698         local has_warning=false
13699
13700         rm -rf $DIR/$tdir
13701         mkdir -p $DIR/$tdir
13702
13703         # block size of mds1
13704         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13705         set_dir_limits $maxsize $((maxsize * 6 / 8))
13706         stack_trap "set_dir_limits 0 0"
13707         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13708         local dirsize=$(stat -c%s "$DIR/$tdir")
13709         local nfiles=0
13710         while (( $dirsize <= $maxsize )); do
13711                 $MCREATE $DIR/$tdir/file_base_$nfiles
13712                 rc=$?
13713                 # check two errors:
13714                 # ENOSPC for ext4 max_dir_size, which has been used since
13715                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13716                 if (( rc == ENOSPC )); then
13717                         set_dir_limits 0 0
13718                         echo "rc=$rc returned as expected after $nfiles files"
13719
13720                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13721                                 error "create failed w/o dir size limit"
13722
13723                         # messages may be rate limited if test is run repeatedly
13724                         check_mds_dmesg '"is approaching max"' ||
13725                                 echo "warning message should be output"
13726                         check_mds_dmesg '"has reached max"' ||
13727                                 echo "reached message should be output"
13728
13729                         dirsize=$(stat -c%s "$DIR/$tdir")
13730
13731                         [[ $dirsize -ge $maxsize ]] && return 0
13732                         error "dirsize $dirsize < $maxsize after $nfiles files"
13733                 elif (( rc != 0 )); then
13734                         break
13735                 fi
13736                 nfiles=$((nfiles + 1))
13737                 dirsize=$(stat -c%s "$DIR/$tdir")
13738         done
13739
13740         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13741 }
13742 run_test 129 "test directory size limit ========================"
13743
13744 OLDIFS="$IFS"
13745 cleanup_130() {
13746         trap 0
13747         IFS="$OLDIFS"
13748 }
13749
13750 test_130a() {
13751         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13752         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13753
13754         trap cleanup_130 EXIT RETURN
13755
13756         local fm_file=$DIR/$tfile
13757         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13758         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13759                 error "dd failed for $fm_file"
13760
13761         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13762         filefrag -ves $fm_file
13763         RC=$?
13764         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13765                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13766         [ $RC != 0 ] && error "filefrag $fm_file failed"
13767
13768         filefrag_op=$(filefrag -ve -k $fm_file |
13769                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13770         lun=$($LFS getstripe -i $fm_file)
13771
13772         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13773         IFS=$'\n'
13774         tot_len=0
13775         for line in $filefrag_op
13776         do
13777                 frag_lun=`echo $line | cut -d: -f5`
13778                 ext_len=`echo $line | cut -d: -f4`
13779                 if (( $frag_lun != $lun )); then
13780                         cleanup_130
13781                         error "FIEMAP on 1-stripe file($fm_file) failed"
13782                         return
13783                 fi
13784                 (( tot_len += ext_len ))
13785         done
13786
13787         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13788                 cleanup_130
13789                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13790                 return
13791         fi
13792
13793         cleanup_130
13794
13795         echo "FIEMAP on single striped file succeeded"
13796 }
13797 run_test 130a "FIEMAP (1-stripe file)"
13798
13799 test_130b() {
13800         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13801
13802         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13803         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13804
13805         trap cleanup_130 EXIT RETURN
13806
13807         local fm_file=$DIR/$tfile
13808         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13809                         error "setstripe on $fm_file"
13810         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13811                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13812
13813         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13814                 error "dd failed on $fm_file"
13815
13816         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13817         filefrag_op=$(filefrag -ve -k $fm_file |
13818                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13819
13820         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13821                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13822
13823         IFS=$'\n'
13824         tot_len=0
13825         num_luns=1
13826         for line in $filefrag_op
13827         do
13828                 frag_lun=$(echo $line | cut -d: -f5 |
13829                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13830                 ext_len=$(echo $line | cut -d: -f4)
13831                 if (( $frag_lun != $last_lun )); then
13832                         if (( tot_len != 1024 )); then
13833                                 cleanup_130
13834                                 error "FIEMAP on $fm_file failed; returned " \
13835                                 "len $tot_len for OST $last_lun instead of 1024"
13836                                 return
13837                         else
13838                                 (( num_luns += 1 ))
13839                                 tot_len=0
13840                         fi
13841                 fi
13842                 (( tot_len += ext_len ))
13843                 last_lun=$frag_lun
13844         done
13845         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13846                 cleanup_130
13847                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13848                         "luns or wrong len for OST $last_lun"
13849                 return
13850         fi
13851
13852         cleanup_130
13853
13854         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13855 }
13856 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13857
13858 test_130c() {
13859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13860
13861         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13862         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13863
13864         trap cleanup_130 EXIT RETURN
13865
13866         local fm_file=$DIR/$tfile
13867         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13868         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13869                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13870
13871         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13872                         error "dd failed on $fm_file"
13873
13874         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13875         filefrag_op=$(filefrag -ve -k $fm_file |
13876                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13877
13878         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13879                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13880
13881         IFS=$'\n'
13882         tot_len=0
13883         num_luns=1
13884         for line in $filefrag_op
13885         do
13886                 frag_lun=$(echo $line | cut -d: -f5 |
13887                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13888                 ext_len=$(echo $line | cut -d: -f4)
13889                 if (( $frag_lun != $last_lun )); then
13890                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13891                         if (( logical != 512 )); then
13892                                 cleanup_130
13893                                 error "FIEMAP on $fm_file failed; returned " \
13894                                 "logical start for lun $logical instead of 512"
13895                                 return
13896                         fi
13897                         if (( tot_len != 512 )); then
13898                                 cleanup_130
13899                                 error "FIEMAP on $fm_file failed; returned " \
13900                                 "len $tot_len for OST $last_lun instead of 1024"
13901                                 return
13902                         else
13903                                 (( num_luns += 1 ))
13904                                 tot_len=0
13905                         fi
13906                 fi
13907                 (( tot_len += ext_len ))
13908                 last_lun=$frag_lun
13909         done
13910         if (( num_luns != 2 || tot_len != 512 )); then
13911                 cleanup_130
13912                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13913                         "luns or wrong len for OST $last_lun"
13914                 return
13915         fi
13916
13917         cleanup_130
13918
13919         echo "FIEMAP on 2-stripe file with hole succeeded"
13920 }
13921 run_test 130c "FIEMAP (2-stripe file with hole)"
13922
13923 test_130d() {
13924         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13925
13926         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13927         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13928
13929         trap cleanup_130 EXIT RETURN
13930
13931         local fm_file=$DIR/$tfile
13932         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13933                         error "setstripe on $fm_file"
13934         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13935                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13936
13937         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13938         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13939                 error "dd failed on $fm_file"
13940
13941         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13942         filefrag_op=$(filefrag -ve -k $fm_file |
13943                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13944
13945         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13946                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13947
13948         IFS=$'\n'
13949         tot_len=0
13950         num_luns=1
13951         for line in $filefrag_op
13952         do
13953                 frag_lun=$(echo $line | cut -d: -f5 |
13954                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13955                 ext_len=$(echo $line | cut -d: -f4)
13956                 if (( $frag_lun != $last_lun )); then
13957                         if (( tot_len != 1024 )); then
13958                                 cleanup_130
13959                                 error "FIEMAP on $fm_file failed; returned " \
13960                                 "len $tot_len for OST $last_lun instead of 1024"
13961                                 return
13962                         else
13963                                 (( num_luns += 1 ))
13964                                 tot_len=0
13965                         fi
13966                 fi
13967                 (( tot_len += ext_len ))
13968                 last_lun=$frag_lun
13969         done
13970         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13971                 cleanup_130
13972                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13973                         "luns or wrong len for OST $last_lun"
13974                 return
13975         fi
13976
13977         cleanup_130
13978
13979         echo "FIEMAP on N-stripe file succeeded"
13980 }
13981 run_test 130d "FIEMAP (N-stripe file)"
13982
13983 test_130e() {
13984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13985
13986         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13987         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13988
13989         trap cleanup_130 EXIT RETURN
13990
13991         local fm_file=$DIR/$tfile
13992         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13993
13994         NUM_BLKS=512
13995         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13996         for ((i = 0; i < $NUM_BLKS; i++)); do
13997                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13998                         conv=notrunc > /dev/null 2>&1
13999         done
14000
14001         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14002         filefrag_op=$(filefrag -ve -k $fm_file |
14003                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14004
14005         last_lun=$(echo $filefrag_op | cut -d: -f5)
14006
14007         IFS=$'\n'
14008         tot_len=0
14009         num_luns=1
14010         for line in $filefrag_op; do
14011                 frag_lun=$(echo $line | cut -d: -f5)
14012                 ext_len=$(echo $line | cut -d: -f4)
14013                 if [[ "$frag_lun" != "$last_lun" ]]; then
14014                         if (( tot_len != $EXPECTED_LEN )); then
14015                                 cleanup_130
14016                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14017                         else
14018                                 (( num_luns += 1 ))
14019                                 tot_len=0
14020                         fi
14021                 fi
14022                 (( tot_len += ext_len ))
14023                 last_lun=$frag_lun
14024         done
14025         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14026                 cleanup_130
14027                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14028         fi
14029
14030         echo "FIEMAP with continuation calls succeeded"
14031 }
14032 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14033
14034 test_130f() {
14035         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14036         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14037
14038         local fm_file=$DIR/$tfile
14039         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14040                 error "multiop create with lov_delay_create on $fm_file"
14041
14042         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14043         filefrag_extents=$(filefrag -vek $fm_file |
14044                            awk '/extents? found/ { print $2 }')
14045         if [[ "$filefrag_extents" != "0" ]]; then
14046                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14047         fi
14048
14049         rm -f $fm_file
14050 }
14051 run_test 130f "FIEMAP (unstriped file)"
14052
14053 test_130g() {
14054         local file=$DIR/$tfile
14055         local nr=$((OSTCOUNT * 100))
14056
14057         $LFS setstripe -C $nr $file ||
14058                 error "failed to setstripe -C $nr $file"
14059
14060         dd if=/dev/zero of=$file count=$nr bs=1M
14061         sync
14062         nr=$($LFS getstripe -c $file)
14063
14064         local extents=$(filefrag -v $file |
14065                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14066
14067         echo "filefrag list $extents extents in file with stripecount $nr"
14068         if (( extents < nr )); then
14069                 $LFS getstripe $file
14070                 filefrag -v $file
14071                 error "filefrag printed $extents < $nr extents"
14072         fi
14073
14074         rm -f $file
14075 }
14076 run_test 130g "FIEMAP (overstripe file)"
14077
14078 # Test for writev/readv
14079 test_131a() {
14080         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14081                 error "writev test failed"
14082         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14083                 error "readv failed"
14084         rm -f $DIR/$tfile
14085 }
14086 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14087
14088 test_131b() {
14089         local fsize=$((524288 + 1048576 + 1572864))
14090         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14091                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14092                         error "append writev test failed"
14093
14094         ((fsize += 1572864 + 1048576))
14095         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14096                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14097                         error "append writev test failed"
14098         rm -f $DIR/$tfile
14099 }
14100 run_test 131b "test append writev"
14101
14102 test_131c() {
14103         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14104         error "NOT PASS"
14105 }
14106 run_test 131c "test read/write on file w/o objects"
14107
14108 test_131d() {
14109         rwv -f $DIR/$tfile -w -n 1 1572864
14110         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14111         if [ "$NOB" != 1572864 ]; then
14112                 error "Short read filed: read $NOB bytes instead of 1572864"
14113         fi
14114         rm -f $DIR/$tfile
14115 }
14116 run_test 131d "test short read"
14117
14118 test_131e() {
14119         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14120         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14121         error "read hitting hole failed"
14122         rm -f $DIR/$tfile
14123 }
14124 run_test 131e "test read hitting hole"
14125
14126 check_stats() {
14127         local facet=$1
14128         local op=$2
14129         local want=${3:-0}
14130         local res
14131
14132         case $facet in
14133         mds*) res=$(do_facet $facet \
14134                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14135                  ;;
14136         ost*) res=$(do_facet $facet \
14137                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14138                  ;;
14139         *) error "Wrong facet '$facet'" ;;
14140         esac
14141         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14142         # if the argument $3 is zero, it means any stat increment is ok.
14143         if [[ $want -gt 0 ]]; then
14144                 local count=$(echo $res | awk '{ print $2 }')
14145                 [[ $count -ne $want ]] &&
14146                         error "The $op counter on $facet is $count, not $want"
14147         fi
14148 }
14149
14150 test_133a() {
14151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14152         remote_ost_nodsh && skip "remote OST with nodsh"
14153         remote_mds_nodsh && skip "remote MDS with nodsh"
14154         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14155                 skip_env "MDS doesn't support rename stats"
14156
14157         local testdir=$DIR/${tdir}/stats_testdir
14158
14159         mkdir -p $DIR/${tdir}
14160
14161         # clear stats.
14162         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14163         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14164
14165         # verify mdt stats first.
14166         mkdir ${testdir} || error "mkdir failed"
14167         check_stats $SINGLEMDS "mkdir" 1
14168         touch ${testdir}/${tfile} || error "touch failed"
14169         check_stats $SINGLEMDS "open" 1
14170         check_stats $SINGLEMDS "close" 1
14171         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14172                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14173                 check_stats $SINGLEMDS "mknod" 2
14174         }
14175         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14176         check_stats $SINGLEMDS "unlink" 1
14177         rm -f ${testdir}/${tfile} || error "file remove failed"
14178         check_stats $SINGLEMDS "unlink" 2
14179
14180         # remove working dir and check mdt stats again.
14181         rmdir ${testdir} || error "rmdir failed"
14182         check_stats $SINGLEMDS "rmdir" 1
14183
14184         local testdir1=$DIR/${tdir}/stats_testdir1
14185         mkdir -p ${testdir}
14186         mkdir -p ${testdir1}
14187         touch ${testdir1}/test1
14188         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14189         check_stats $SINGLEMDS "crossdir_rename" 1
14190
14191         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14192         check_stats $SINGLEMDS "samedir_rename" 1
14193
14194         rm -rf $DIR/${tdir}
14195 }
14196 run_test 133a "Verifying MDT stats ========================================"
14197
14198 test_133b() {
14199         local res
14200
14201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14202         remote_ost_nodsh && skip "remote OST with nodsh"
14203         remote_mds_nodsh && skip "remote MDS with nodsh"
14204
14205         local testdir=$DIR/${tdir}/stats_testdir
14206
14207         mkdir -p ${testdir} || error "mkdir failed"
14208         touch ${testdir}/${tfile} || error "touch failed"
14209         cancel_lru_locks mdc
14210
14211         # clear stats.
14212         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14213         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14214
14215         # extra mdt stats verification.
14216         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14217         check_stats $SINGLEMDS "setattr" 1
14218         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14219         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14220         then            # LU-1740
14221                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14222                 check_stats $SINGLEMDS "getattr" 1
14223         fi
14224         rm -rf $DIR/${tdir}
14225
14226         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14227         # so the check below is not reliable
14228         [ $MDSCOUNT -eq 1 ] || return 0
14229
14230         # Sleep to avoid a cached response.
14231         #define OBD_STATFS_CACHE_SECONDS 1
14232         sleep 2
14233         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14234         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14235         $LFS df || error "lfs failed"
14236         check_stats $SINGLEMDS "statfs" 1
14237
14238         # check aggregated statfs (LU-10018)
14239         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14240                 return 0
14241         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14242                 return 0
14243         sleep 2
14244         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14245         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14246         df $DIR
14247         check_stats $SINGLEMDS "statfs" 1
14248
14249         # We want to check that the client didn't send OST_STATFS to
14250         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14251         # extra care is needed here.
14252         if remote_mds; then
14253                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14254                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14255
14256                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14257                 [ "$res" ] && error "OST got STATFS"
14258         fi
14259
14260         return 0
14261 }
14262 run_test 133b "Verifying extra MDT stats =================================="
14263
14264 test_133c() {
14265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14266         remote_ost_nodsh && skip "remote OST with nodsh"
14267         remote_mds_nodsh && skip "remote MDS with nodsh"
14268
14269         local testdir=$DIR/$tdir/stats_testdir
14270
14271         test_mkdir -p $testdir
14272
14273         # verify obdfilter stats.
14274         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14275         sync
14276         cancel_lru_locks osc
14277         wait_delete_completed
14278
14279         # clear stats.
14280         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14281         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14282
14283         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14284                 error "dd failed"
14285         sync
14286         cancel_lru_locks osc
14287         check_stats ost1 "write" 1
14288
14289         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14290         check_stats ost1 "read" 1
14291
14292         > $testdir/$tfile || error "truncate failed"
14293         check_stats ost1 "punch" 1
14294
14295         rm -f $testdir/$tfile || error "file remove failed"
14296         wait_delete_completed
14297         check_stats ost1 "destroy" 1
14298
14299         rm -rf $DIR/$tdir
14300 }
14301 run_test 133c "Verifying OST stats ========================================"
14302
14303 order_2() {
14304         local value=$1
14305         local orig=$value
14306         local order=1
14307
14308         while [ $value -ge 2 ]; do
14309                 order=$((order*2))
14310                 value=$((value/2))
14311         done
14312
14313         if [ $orig -gt $order ]; then
14314                 order=$((order*2))
14315         fi
14316         echo $order
14317 }
14318
14319 size_in_KMGT() {
14320     local value=$1
14321     local size=('K' 'M' 'G' 'T');
14322     local i=0
14323     local size_string=$value
14324
14325     while [ $value -ge 1024 ]; do
14326         if [ $i -gt 3 ]; then
14327             #T is the biggest unit we get here, if that is bigger,
14328             #just return XXXT
14329             size_string=${value}T
14330             break
14331         fi
14332         value=$((value >> 10))
14333         if [ $value -lt 1024 ]; then
14334             size_string=${value}${size[$i]}
14335             break
14336         fi
14337         i=$((i + 1))
14338     done
14339
14340     echo $size_string
14341 }
14342
14343 get_rename_size() {
14344         local size=$1
14345         local context=${2:-.}
14346         local sample=$(do_facet $SINGLEMDS $LCTL \
14347                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14348                 grep -A1 $context |
14349                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14350         echo $sample
14351 }
14352
14353 test_133d() {
14354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14355         remote_ost_nodsh && skip "remote OST with nodsh"
14356         remote_mds_nodsh && skip "remote MDS with nodsh"
14357         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14358                 skip_env "MDS doesn't support rename stats"
14359
14360         local testdir1=$DIR/${tdir}/stats_testdir1
14361         local testdir2=$DIR/${tdir}/stats_testdir2
14362         mkdir -p $DIR/${tdir}
14363
14364         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14365
14366         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14367         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14368
14369         createmany -o $testdir1/test 512 || error "createmany failed"
14370
14371         # check samedir rename size
14372         mv ${testdir1}/test0 ${testdir1}/test_0
14373
14374         local testdir1_size=$(ls -l $DIR/${tdir} |
14375                 awk '/stats_testdir1/ {print $5}')
14376         local testdir2_size=$(ls -l $DIR/${tdir} |
14377                 awk '/stats_testdir2/ {print $5}')
14378
14379         testdir1_size=$(order_2 $testdir1_size)
14380         testdir2_size=$(order_2 $testdir2_size)
14381
14382         testdir1_size=$(size_in_KMGT $testdir1_size)
14383         testdir2_size=$(size_in_KMGT $testdir2_size)
14384
14385         echo "source rename dir size: ${testdir1_size}"
14386         echo "target rename dir size: ${testdir2_size}"
14387
14388         local cmd="do_facet $SINGLEMDS $LCTL "
14389         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14390
14391         eval $cmd || error "$cmd failed"
14392         local samedir=$($cmd | grep 'same_dir')
14393         local same_sample=$(get_rename_size $testdir1_size)
14394         [ -z "$samedir" ] && error "samedir_rename_size count error"
14395         [[ $same_sample -eq 1 ]] ||
14396                 error "samedir_rename_size error $same_sample"
14397         echo "Check same dir rename stats success"
14398
14399         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14400
14401         # check crossdir rename size
14402         mv ${testdir1}/test_0 ${testdir2}/test_0
14403
14404         testdir1_size=$(ls -l $DIR/${tdir} |
14405                 awk '/stats_testdir1/ {print $5}')
14406         testdir2_size=$(ls -l $DIR/${tdir} |
14407                 awk '/stats_testdir2/ {print $5}')
14408
14409         testdir1_size=$(order_2 $testdir1_size)
14410         testdir2_size=$(order_2 $testdir2_size)
14411
14412         testdir1_size=$(size_in_KMGT $testdir1_size)
14413         testdir2_size=$(size_in_KMGT $testdir2_size)
14414
14415         echo "source rename dir size: ${testdir1_size}"
14416         echo "target rename dir size: ${testdir2_size}"
14417
14418         eval $cmd || error "$cmd failed"
14419         local crossdir=$($cmd | grep 'crossdir')
14420         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14421         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14422         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14423         [[ $src_sample -eq 1 ]] ||
14424                 error "crossdir_rename_size error $src_sample"
14425         [[ $tgt_sample -eq 1 ]] ||
14426                 error "crossdir_rename_size error $tgt_sample"
14427         echo "Check cross dir rename stats success"
14428         rm -rf $DIR/${tdir}
14429 }
14430 run_test 133d "Verifying rename_stats ========================================"
14431
14432 test_133e() {
14433         remote_mds_nodsh && skip "remote MDS with nodsh"
14434         remote_ost_nodsh && skip "remote OST with nodsh"
14435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14436
14437         local testdir=$DIR/${tdir}/stats_testdir
14438         local ctr f0 f1 bs=32768 count=42 sum
14439
14440         mkdir -p ${testdir} || error "mkdir failed"
14441
14442         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14443
14444         for ctr in {write,read}_bytes; do
14445                 sync
14446                 cancel_lru_locks osc
14447
14448                 do_facet ost1 $LCTL set_param -n \
14449                         "obdfilter.*.exports.clear=clear"
14450
14451                 if [ $ctr = write_bytes ]; then
14452                         f0=/dev/zero
14453                         f1=${testdir}/${tfile}
14454                 else
14455                         f0=${testdir}/${tfile}
14456                         f1=/dev/null
14457                 fi
14458
14459                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14460                         error "dd failed"
14461                 sync
14462                 cancel_lru_locks osc
14463
14464                 sum=$(do_facet ost1 $LCTL get_param \
14465                         "obdfilter.*.exports.*.stats" |
14466                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14467                                 $1 == ctr { sum += $7 }
14468                                 END { printf("%0.0f", sum) }')
14469
14470                 if ((sum != bs * count)); then
14471                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14472                 fi
14473         done
14474
14475         rm -rf $DIR/${tdir}
14476 }
14477 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14478
14479 test_133f() {
14480         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14481                 skip "too old lustre for get_param -R ($facet_ver)"
14482
14483         # verifying readability.
14484         $LCTL get_param -R '*' &> /dev/null
14485
14486         # Verifing writability with badarea_io.
14487         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14488         local skipped_params='force_lbug|changelog_mask|daemon_file'
14489         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14490                 egrep -v "$skipped_params" |
14491                 xargs -n 1 find $proc_dirs -name |
14492                 xargs -n 1 badarea_io ||
14493                 error "client badarea_io failed"
14494
14495         # remount the FS in case writes/reads /proc break the FS
14496         cleanup || error "failed to unmount"
14497         setup || error "failed to setup"
14498 }
14499 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14500
14501 test_133g() {
14502         remote_mds_nodsh && skip "remote MDS with nodsh"
14503         remote_ost_nodsh && skip "remote OST with nodsh"
14504
14505         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14506         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14507         local facet
14508         for facet in mds1 ost1; do
14509                 local facet_ver=$(lustre_version_code $facet)
14510                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14511                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14512                 else
14513                         log "$facet: too old lustre for get_param -R"
14514                 fi
14515                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14516                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14517                                 tr -d = | egrep -v $skipped_params |
14518                                 xargs -n 1 find $proc_dirs -name |
14519                                 xargs -n 1 badarea_io" ||
14520                                         error "$facet badarea_io failed"
14521                 else
14522                         skip_noexit "$facet: too old lustre for get_param -R"
14523                 fi
14524         done
14525
14526         # remount the FS in case writes/reads /proc break the FS
14527         cleanup || error "failed to unmount"
14528         setup || error "failed to setup"
14529 }
14530 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14531
14532 test_133h() {
14533         remote_mds_nodsh && skip "remote MDS with nodsh"
14534         remote_ost_nodsh && skip "remote OST with nodsh"
14535         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14536                 skip "Need MDS version at least 2.9.54"
14537
14538         local facet
14539         for facet in client mds1 ost1; do
14540                 # Get the list of files that are missing the terminating newline
14541                 local plist=$(do_facet $facet
14542                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14543                 local ent
14544                 for ent in $plist; do
14545                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14546                                 awk -v FS='\v' -v RS='\v\v' \
14547                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14548                                         print FILENAME}'" 2>/dev/null)
14549                         [ -z $missing ] || {
14550                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14551                                 error "file does not end with newline: $facet-$ent"
14552                         }
14553                 done
14554         done
14555 }
14556 run_test 133h "Proc files should end with newlines"
14557
14558 test_134a() {
14559         remote_mds_nodsh && skip "remote MDS with nodsh"
14560         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14561                 skip "Need MDS version at least 2.7.54"
14562
14563         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14564         cancel_lru_locks mdc
14565
14566         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14567         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14568         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14569
14570         local nr=1000
14571         createmany -o $DIR/$tdir/f $nr ||
14572                 error "failed to create $nr files in $DIR/$tdir"
14573         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14574
14575         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14576         do_facet mds1 $LCTL set_param fail_loc=0x327
14577         do_facet mds1 $LCTL set_param fail_val=500
14578         touch $DIR/$tdir/m
14579
14580         echo "sleep 10 seconds ..."
14581         sleep 10
14582         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14583
14584         do_facet mds1 $LCTL set_param fail_loc=0
14585         do_facet mds1 $LCTL set_param fail_val=0
14586         [ $lck_cnt -lt $unused ] ||
14587                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14588
14589         rm $DIR/$tdir/m
14590         unlinkmany $DIR/$tdir/f $nr
14591 }
14592 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14593
14594 test_134b() {
14595         remote_mds_nodsh && skip "remote MDS with nodsh"
14596         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14597                 skip "Need MDS version at least 2.7.54"
14598
14599         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14600         cancel_lru_locks mdc
14601
14602         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14603                         ldlm.lock_reclaim_threshold_mb)
14604         # disable reclaim temporarily
14605         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14606
14607         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14608         do_facet mds1 $LCTL set_param fail_loc=0x328
14609         do_facet mds1 $LCTL set_param fail_val=500
14610
14611         $LCTL set_param debug=+trace
14612
14613         local nr=600
14614         createmany -o $DIR/$tdir/f $nr &
14615         local create_pid=$!
14616
14617         echo "Sleep $TIMEOUT seconds ..."
14618         sleep $TIMEOUT
14619         if ! ps -p $create_pid  > /dev/null 2>&1; then
14620                 do_facet mds1 $LCTL set_param fail_loc=0
14621                 do_facet mds1 $LCTL set_param fail_val=0
14622                 do_facet mds1 $LCTL set_param \
14623                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14624                 error "createmany finished incorrectly!"
14625         fi
14626         do_facet mds1 $LCTL set_param fail_loc=0
14627         do_facet mds1 $LCTL set_param fail_val=0
14628         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14629         wait $create_pid || return 1
14630
14631         unlinkmany $DIR/$tdir/f $nr
14632 }
14633 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14634
14635 test_135() {
14636         remote_mds_nodsh && skip "remote MDS with nodsh"
14637         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14638                 skip "Need MDS version at least 2.13.50"
14639         local fname
14640
14641         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14642
14643 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14644         #set only one record at plain llog
14645         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14646
14647         #fill already existed plain llog each 64767
14648         #wrapping whole catalog
14649         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14650
14651         createmany -o $DIR/$tdir/$tfile_ 64700
14652         for (( i = 0; i < 64700; i = i + 2 ))
14653         do
14654                 rm $DIR/$tdir/$tfile_$i &
14655                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14656                 local pid=$!
14657                 wait $pid
14658         done
14659
14660         #waiting osp synchronization
14661         wait_delete_completed
14662 }
14663 run_test 135 "Race catalog processing"
14664
14665 test_136() {
14666         remote_mds_nodsh && skip "remote MDS with nodsh"
14667         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14668                 skip "Need MDS version at least 2.13.50"
14669         local fname
14670
14671         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14672         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14673         #set only one record at plain llog
14674 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14675         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14676
14677         #fill already existed 2 plain llogs each 64767
14678         #wrapping whole catalog
14679         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14680         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14681         wait_delete_completed
14682
14683         createmany -o $DIR/$tdir/$tfile_ 10
14684         sleep 25
14685
14686         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14687         for (( i = 0; i < 10; i = i + 3 ))
14688         do
14689                 rm $DIR/$tdir/$tfile_$i &
14690                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14691                 local pid=$!
14692                 wait $pid
14693                 sleep 7
14694                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14695         done
14696
14697         #waiting osp synchronization
14698         wait_delete_completed
14699 }
14700 run_test 136 "Race catalog processing 2"
14701
14702 test_140() { #bug-17379
14703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14704
14705         test_mkdir $DIR/$tdir
14706         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14707         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14708
14709         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14710         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14711         local i=0
14712         while i=$((i + 1)); do
14713                 test_mkdir $i
14714                 cd $i || error "Changing to $i"
14715                 ln -s ../stat stat || error "Creating stat symlink"
14716                 # Read the symlink until ELOOP present,
14717                 # not LBUGing the system is considered success,
14718                 # we didn't overrun the stack.
14719                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14720                 if [ $ret -ne 0 ]; then
14721                         if [ $ret -eq 40 ]; then
14722                                 break  # -ELOOP
14723                         else
14724                                 error "Open stat symlink"
14725                                         return
14726                         fi
14727                 fi
14728         done
14729         i=$((i - 1))
14730         echo "The symlink depth = $i"
14731         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14732                 error "Invalid symlink depth"
14733
14734         # Test recursive symlink
14735         ln -s symlink_self symlink_self
14736         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14737         echo "open symlink_self returns $ret"
14738         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14739 }
14740 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14741
14742 test_150a() {
14743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14744
14745         local TF="$TMP/$tfile"
14746
14747         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14748         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14749         cp $TF $DIR/$tfile
14750         cancel_lru_locks $OSC
14751         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14752         remount_client $MOUNT
14753         df -P $MOUNT
14754         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14755
14756         $TRUNCATE $TF 6000
14757         $TRUNCATE $DIR/$tfile 6000
14758         cancel_lru_locks $OSC
14759         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14760
14761         echo "12345" >>$TF
14762         echo "12345" >>$DIR/$tfile
14763         cancel_lru_locks $OSC
14764         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14765
14766         echo "12345" >>$TF
14767         echo "12345" >>$DIR/$tfile
14768         cancel_lru_locks $OSC
14769         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14770 }
14771 run_test 150a "truncate/append tests"
14772
14773 test_150b() {
14774         check_set_fallocate_or_skip
14775
14776         touch $DIR/$tfile
14777         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14778         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14779 }
14780 run_test 150b "Verify fallocate (prealloc) functionality"
14781
14782 test_150bb() {
14783         check_set_fallocate_or_skip
14784
14785         touch $DIR/$tfile
14786         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14787         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14788         > $DIR/$tfile
14789         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14790         # precomputed md5sum for 20MB of zeroes
14791         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14792         local sum=($(md5sum $DIR/$tfile))
14793
14794         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14795
14796         check_set_fallocate 1
14797
14798         > $DIR/$tfile
14799         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14800         sum=($(md5sum $DIR/$tfile))
14801
14802         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14803 }
14804 run_test 150bb "Verify fallocate modes both zero space"
14805
14806 test_150c() {
14807         check_set_fallocate_or_skip
14808         local striping="-c2"
14809
14810         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14811         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14812         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14813         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14814         local want=$((OSTCOUNT * 1048576))
14815
14816         # Must allocate all requested space, not more than 5% extra
14817         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14818                 error "bytes $bytes is not $want"
14819
14820         rm -f $DIR/$tfile
14821
14822         echo "verify fallocate on PFL file"
14823
14824         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14825
14826         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14827                 error "Create $DIR/$tfile failed"
14828         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14829         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14830         want=$((512 * 1048576))
14831
14832         # Must allocate all requested space, not more than 5% extra
14833         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14834                 error "bytes $bytes is not $want"
14835 }
14836 run_test 150c "Verify fallocate Size and Blocks"
14837
14838 test_150d() {
14839         check_set_fallocate_or_skip
14840         local striping="-c2"
14841
14842         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14843
14844         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14845         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14846                 error "setstripe failed"
14847         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14848         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14849         local want=$((OSTCOUNT * 1048576))
14850
14851         # Must allocate all requested space, not more than 5% extra
14852         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14853                 error "bytes $bytes is not $want"
14854 }
14855 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14856
14857 test_150e() {
14858         check_set_fallocate_or_skip
14859
14860         echo "df before:"
14861         $LFS df
14862         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14863         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14864                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14865
14866         # Find OST with Minimum Size
14867         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14868                        sort -un | head -1)
14869
14870         # Get 100MB per OST of the available space to reduce run time
14871         # else 60% of the available space if we are running SLOW tests
14872         if [ $SLOW == "no" ]; then
14873                 local space=$((1024 * 100 * OSTCOUNT))
14874         else
14875                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14876         fi
14877
14878         fallocate -l${space}k $DIR/$tfile ||
14879                 error "fallocate ${space}k $DIR/$tfile failed"
14880         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14881
14882         # get size immediately after fallocate. This should be correctly
14883         # updated
14884         local size=$(stat -c '%s' $DIR/$tfile)
14885         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14886
14887         # Sleep for a while for statfs to get updated. And not pull from cache.
14888         sleep 2
14889
14890         echo "df after fallocate:"
14891         $LFS df
14892
14893         (( size / 1024 == space )) || error "size $size != requested $space"
14894         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14895                 error "used $used < space $space"
14896
14897         rm $DIR/$tfile || error "rm failed"
14898         sync
14899         wait_delete_completed
14900
14901         echo "df after unlink:"
14902         $LFS df
14903 }
14904 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14905
14906 test_150f() {
14907         local size
14908         local blocks
14909         local want_size_before=20480 # in bytes
14910         local want_blocks_before=40 # 512 sized blocks
14911         local want_blocks_after=24  # 512 sized blocks
14912         local length=$(((want_blocks_before - want_blocks_after) * 512))
14913
14914         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14915                 skip "need at least 2.14.0 for fallocate punch"
14916
14917         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14918                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14919         fi
14920
14921         check_set_fallocate_or_skip
14922         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14923
14924         [[ "x$DOM" == "xyes" ]] &&
14925                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14926
14927         echo "Verify fallocate punch: Range within the file range"
14928         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14929                 error "dd failed for bs 4096 and count 5"
14930
14931         # Call fallocate with punch range which is within the file range
14932         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14933                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14934         # client must see changes immediately after fallocate
14935         size=$(stat -c '%s' $DIR/$tfile)
14936         blocks=$(stat -c '%b' $DIR/$tfile)
14937
14938         # Verify punch worked.
14939         (( blocks == want_blocks_after )) ||
14940                 error "punch failed: blocks $blocks != $want_blocks_after"
14941
14942         (( size == want_size_before )) ||
14943                 error "punch failed: size $size != $want_size_before"
14944
14945         # Verify there is hole in file
14946         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14947         # precomputed md5sum
14948         local expect="4a9a834a2db02452929c0a348273b4aa"
14949
14950         cksum=($(md5sum $DIR/$tfile))
14951         [[ "${cksum[0]}" == "$expect" ]] ||
14952                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14953
14954         # Start second sub-case for fallocate punch.
14955         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14956         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14957                 error "dd failed for bs 4096 and count 5"
14958
14959         # Punch range less than block size will have no change in block count
14960         want_blocks_after=40  # 512 sized blocks
14961
14962         # Punch overlaps two blocks and less than blocksize
14963         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14964                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14965         size=$(stat -c '%s' $DIR/$tfile)
14966         blocks=$(stat -c '%b' $DIR/$tfile)
14967
14968         # Verify punch worked.
14969         (( blocks == want_blocks_after )) ||
14970                 error "punch failed: blocks $blocks != $want_blocks_after"
14971
14972         (( size == want_size_before )) ||
14973                 error "punch failed: size $size != $want_size_before"
14974
14975         # Verify if range is really zero'ed out. We expect Zeros.
14976         # precomputed md5sum
14977         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14978         cksum=($(md5sum $DIR/$tfile))
14979         [[ "${cksum[0]}" == "$expect" ]] ||
14980                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14981 }
14982 run_test 150f "Verify fallocate punch functionality"
14983
14984 test_150g() {
14985         local space
14986         local size
14987         local blocks
14988         local blocks_after
14989         local size_after
14990         local BS=4096 # Block size in bytes
14991
14992         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14993                 skip "need at least 2.14.0 for fallocate punch"
14994
14995         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14996                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14997         fi
14998
14999         check_set_fallocate_or_skip
15000         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15001
15002         if [[ "x$DOM" == "xyes" ]]; then
15003                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15004                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15005         else
15006                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15007                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15008         fi
15009
15010         # Get 100MB per OST of the available space to reduce run time
15011         # else 60% of the available space if we are running SLOW tests
15012         if [ $SLOW == "no" ]; then
15013                 space=$((1024 * 100 * OSTCOUNT))
15014         else
15015                 # Find OST with Minimum Size
15016                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15017                         sort -un | head -1)
15018                 echo "min size OST: $space"
15019                 space=$(((space * 60)/100 * OSTCOUNT))
15020         fi
15021         # space in 1k units, round to 4k blocks
15022         local blkcount=$((space * 1024 / $BS))
15023
15024         echo "Verify fallocate punch: Very large Range"
15025         fallocate -l${space}k $DIR/$tfile ||
15026                 error "fallocate ${space}k $DIR/$tfile failed"
15027         # write 1M at the end, start and in the middle
15028         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15029                 error "dd failed: bs $BS count 256"
15030         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15031                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15032         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15033                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15034
15035         # Gather stats.
15036         size=$(stat -c '%s' $DIR/$tfile)
15037
15038         # gather punch length.
15039         local punch_size=$((size - (BS * 2)))
15040
15041         echo "punch_size = $punch_size"
15042         echo "size - punch_size: $((size - punch_size))"
15043         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15044
15045         # Call fallocate to punch all except 2 blocks. We leave the
15046         # first and the last block
15047         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15048         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15049                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15050
15051         size_after=$(stat -c '%s' $DIR/$tfile)
15052         blocks_after=$(stat -c '%b' $DIR/$tfile)
15053
15054         # Verify punch worked.
15055         # Size should be kept
15056         (( size == size_after )) ||
15057                 error "punch failed: size $size != $size_after"
15058
15059         # two 4k data blocks to remain plus possible 1 extra extent block
15060         (( blocks_after <= ((BS / 512) * 3) )) ||
15061                 error "too many blocks remains: $blocks_after"
15062
15063         # Verify that file has hole between the first and the last blocks
15064         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15065         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15066
15067         echo "Hole at [$hole_start, $hole_end)"
15068         (( hole_start == BS )) ||
15069                 error "no hole at offset $BS after punch"
15070
15071         (( hole_end == BS + punch_size )) ||
15072                 error "data at offset $hole_end < $((BS + punch_size))"
15073 }
15074 run_test 150g "Verify fallocate punch on large range"
15075
15076 #LU-2902 roc_hit was not able to read all values from lproc
15077 function roc_hit_init() {
15078         local list=$(comma_list $(osts_nodes))
15079         local dir=$DIR/$tdir-check
15080         local file=$dir/$tfile
15081         local BEFORE
15082         local AFTER
15083         local idx
15084
15085         test_mkdir $dir
15086         #use setstripe to do a write to every ost
15087         for i in $(seq 0 $((OSTCOUNT-1))); do
15088                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15089                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15090                 idx=$(printf %04x $i)
15091                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15092                         awk '$1 == "cache_access" {sum += $7}
15093                                 END { printf("%0.0f", sum) }')
15094
15095                 cancel_lru_locks osc
15096                 cat $file >/dev/null
15097
15098                 AFTER=$(get_osd_param $list *OST*$idx stats |
15099                         awk '$1 == "cache_access" {sum += $7}
15100                                 END { printf("%0.0f", sum) }')
15101
15102                 echo BEFORE:$BEFORE AFTER:$AFTER
15103                 if ! let "AFTER - BEFORE == 4"; then
15104                         rm -rf $dir
15105                         error "roc_hit is not safe to use"
15106                 fi
15107                 rm $file
15108         done
15109
15110         rm -rf $dir
15111 }
15112
15113 function roc_hit() {
15114         local list=$(comma_list $(osts_nodes))
15115         echo $(get_osd_param $list '' stats |
15116                 awk '$1 == "cache_hit" {sum += $7}
15117                         END { printf("%0.0f", sum) }')
15118 }
15119
15120 function set_cache() {
15121         local on=1
15122
15123         if [ "$2" == "off" ]; then
15124                 on=0;
15125         fi
15126         local list=$(comma_list $(osts_nodes))
15127         set_osd_param $list '' $1_cache_enable $on
15128
15129         cancel_lru_locks osc
15130 }
15131
15132 test_151() {
15133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15134         remote_ost_nodsh && skip "remote OST with nodsh"
15135
15136         local CPAGES=3
15137         local list=$(comma_list $(osts_nodes))
15138
15139         # check whether obdfilter is cache capable at all
15140         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15141                 skip "not cache-capable obdfilter"
15142         fi
15143
15144         # check cache is enabled on all obdfilters
15145         if get_osd_param $list '' read_cache_enable | grep 0; then
15146                 skip "oss cache is disabled"
15147         fi
15148
15149         set_osd_param $list '' writethrough_cache_enable 1
15150
15151         # check write cache is enabled on all obdfilters
15152         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15153                 skip "oss write cache is NOT enabled"
15154         fi
15155
15156         roc_hit_init
15157
15158         #define OBD_FAIL_OBD_NO_LRU  0x609
15159         do_nodes $list $LCTL set_param fail_loc=0x609
15160
15161         # pages should be in the case right after write
15162         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15163                 error "dd failed"
15164
15165         local BEFORE=$(roc_hit)
15166         cancel_lru_locks osc
15167         cat $DIR/$tfile >/dev/null
15168         local AFTER=$(roc_hit)
15169
15170         do_nodes $list $LCTL set_param fail_loc=0
15171
15172         if ! let "AFTER - BEFORE == CPAGES"; then
15173                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15174         fi
15175
15176         cancel_lru_locks osc
15177         # invalidates OST cache
15178         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15179         set_osd_param $list '' read_cache_enable 0
15180         cat $DIR/$tfile >/dev/null
15181
15182         # now data shouldn't be found in the cache
15183         BEFORE=$(roc_hit)
15184         cancel_lru_locks osc
15185         cat $DIR/$tfile >/dev/null
15186         AFTER=$(roc_hit)
15187         if let "AFTER - BEFORE != 0"; then
15188                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15189         fi
15190
15191         set_osd_param $list '' read_cache_enable 1
15192         rm -f $DIR/$tfile
15193 }
15194 run_test 151 "test cache on oss and controls ==============================="
15195
15196 test_152() {
15197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15198
15199         local TF="$TMP/$tfile"
15200
15201         # simulate ENOMEM during write
15202 #define OBD_FAIL_OST_NOMEM      0x226
15203         lctl set_param fail_loc=0x80000226
15204         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15205         cp $TF $DIR/$tfile
15206         sync || error "sync failed"
15207         lctl set_param fail_loc=0
15208
15209         # discard client's cache
15210         cancel_lru_locks osc
15211
15212         # simulate ENOMEM during read
15213         lctl set_param fail_loc=0x80000226
15214         cmp $TF $DIR/$tfile || error "cmp failed"
15215         lctl set_param fail_loc=0
15216
15217         rm -f $TF
15218 }
15219 run_test 152 "test read/write with enomem ============================"
15220
15221 test_153() {
15222         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15223 }
15224 run_test 153 "test if fdatasync does not crash ======================="
15225
15226 dot_lustre_fid_permission_check() {
15227         local fid=$1
15228         local ffid=$MOUNT/.lustre/fid/$fid
15229         local test_dir=$2
15230
15231         echo "stat fid $fid"
15232         stat $ffid > /dev/null || error "stat $ffid failed."
15233         echo "touch fid $fid"
15234         touch $ffid || error "touch $ffid failed."
15235         echo "write to fid $fid"
15236         cat /etc/hosts > $ffid || error "write $ffid failed."
15237         echo "read fid $fid"
15238         diff /etc/hosts $ffid || error "read $ffid failed."
15239         echo "append write to fid $fid"
15240         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15241         echo "rename fid $fid"
15242         mv $ffid $test_dir/$tfile.1 &&
15243                 error "rename $ffid to $tfile.1 should fail."
15244         touch $test_dir/$tfile.1
15245         mv $test_dir/$tfile.1 $ffid &&
15246                 error "rename $tfile.1 to $ffid should fail."
15247         rm -f $test_dir/$tfile.1
15248         echo "truncate fid $fid"
15249         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15250         echo "link fid $fid"
15251         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15252         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15253                 echo "setfacl fid $fid"
15254                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15255                 echo "getfacl fid $fid"
15256                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15257         fi
15258         echo "unlink fid $fid"
15259         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15260         echo "mknod fid $fid"
15261         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15262
15263         fid=[0xf00000400:0x1:0x0]
15264         ffid=$MOUNT/.lustre/fid/$fid
15265
15266         echo "stat non-exist fid $fid"
15267         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15268         echo "write to non-exist fid $fid"
15269         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15270         echo "link new fid $fid"
15271         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15272
15273         mkdir -p $test_dir/$tdir
15274         touch $test_dir/$tdir/$tfile
15275         fid=$($LFS path2fid $test_dir/$tdir)
15276         rc=$?
15277         [ $rc -ne 0 ] &&
15278                 error "error: could not get fid for $test_dir/$dir/$tfile."
15279
15280         ffid=$MOUNT/.lustre/fid/$fid
15281
15282         echo "ls $fid"
15283         ls $ffid > /dev/null || error "ls $ffid failed."
15284         echo "touch $fid/$tfile.1"
15285         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15286
15287         echo "touch $MOUNT/.lustre/fid/$tfile"
15288         touch $MOUNT/.lustre/fid/$tfile && \
15289                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15290
15291         echo "setxattr to $MOUNT/.lustre/fid"
15292         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15293
15294         echo "listxattr for $MOUNT/.lustre/fid"
15295         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15296
15297         echo "delxattr from $MOUNT/.lustre/fid"
15298         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15299
15300         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15301         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15302                 error "touch invalid fid should fail."
15303
15304         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15305         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15306                 error "touch non-normal fid should fail."
15307
15308         echo "rename $tdir to $MOUNT/.lustre/fid"
15309         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15310                 error "rename to $MOUNT/.lustre/fid should fail."
15311
15312         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15313         then            # LU-3547
15314                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15315                 local new_obf_mode=777
15316
15317                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15318                 chmod $new_obf_mode $DIR/.lustre/fid ||
15319                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15320
15321                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15322                 [ $obf_mode -eq $new_obf_mode ] ||
15323                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15324
15325                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15326                 chmod $old_obf_mode $DIR/.lustre/fid ||
15327                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15328         fi
15329
15330         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15331         fid=$($LFS path2fid $test_dir/$tfile-2)
15332
15333         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15334         then # LU-5424
15335                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15336                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15337                         error "create lov data thru .lustre failed"
15338         fi
15339         echo "cp /etc/passwd $test_dir/$tfile-2"
15340         cp /etc/passwd $test_dir/$tfile-2 ||
15341                 error "copy to $test_dir/$tfile-2 failed."
15342         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15343         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15344                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15345
15346         rm -rf $test_dir/tfile.lnk
15347         rm -rf $test_dir/$tfile-2
15348 }
15349
15350 test_154A() {
15351         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15352                 skip "Need MDS version at least 2.4.1"
15353
15354         local tf=$DIR/$tfile
15355         touch $tf
15356
15357         local fid=$($LFS path2fid $tf)
15358         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15359
15360         # check that we get the same pathname back
15361         local rootpath
15362         local found
15363         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15364                 echo "$rootpath $fid"
15365                 found=$($LFS fid2path $rootpath "$fid")
15366                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15367                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15368         done
15369
15370         # check wrong root path format
15371         rootpath=$MOUNT"_wrong"
15372         found=$($LFS fid2path $rootpath "$fid")
15373         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15374 }
15375 run_test 154A "lfs path2fid and fid2path basic checks"
15376
15377 test_154B() {
15378         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15379                 skip "Need MDS version at least 2.4.1"
15380
15381         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15382         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15383         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15384         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15385
15386         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15387         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15388
15389         # check that we get the same pathname
15390         echo "PFID: $PFID, name: $name"
15391         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15392         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15393         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15394                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15395
15396         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15397 }
15398 run_test 154B "verify the ll_decode_linkea tool"
15399
15400 test_154a() {
15401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15402         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15403         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15404                 skip "Need MDS version at least 2.2.51"
15405         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15406
15407         cp /etc/hosts $DIR/$tfile
15408
15409         fid=$($LFS path2fid $DIR/$tfile)
15410         rc=$?
15411         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15412
15413         dot_lustre_fid_permission_check "$fid" $DIR ||
15414                 error "dot lustre permission check $fid failed"
15415
15416         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15417
15418         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15419
15420         touch $MOUNT/.lustre/file &&
15421                 error "creation is not allowed under .lustre"
15422
15423         mkdir $MOUNT/.lustre/dir &&
15424                 error "mkdir is not allowed under .lustre"
15425
15426         rm -rf $DIR/$tfile
15427 }
15428 run_test 154a "Open-by-FID"
15429
15430 test_154b() {
15431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15432         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15433         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15434         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15435                 skip "Need MDS version at least 2.2.51"
15436
15437         local remote_dir=$DIR/$tdir/remote_dir
15438         local MDTIDX=1
15439         local rc=0
15440
15441         mkdir -p $DIR/$tdir
15442         $LFS mkdir -i $MDTIDX $remote_dir ||
15443                 error "create remote directory failed"
15444
15445         cp /etc/hosts $remote_dir/$tfile
15446
15447         fid=$($LFS path2fid $remote_dir/$tfile)
15448         rc=$?
15449         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15450
15451         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15452                 error "dot lustre permission check $fid failed"
15453         rm -rf $DIR/$tdir
15454 }
15455 run_test 154b "Open-by-FID for remote directory"
15456
15457 test_154c() {
15458         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15459                 skip "Need MDS version at least 2.4.1"
15460
15461         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15462         local FID1=$($LFS path2fid $DIR/$tfile.1)
15463         local FID2=$($LFS path2fid $DIR/$tfile.2)
15464         local FID3=$($LFS path2fid $DIR/$tfile.3)
15465
15466         local N=1
15467         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15468                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15469                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15470                 local want=FID$N
15471                 [ "$FID" = "${!want}" ] ||
15472                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15473                 N=$((N + 1))
15474         done
15475
15476         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15477         do
15478                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15479                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15480                 N=$((N + 1))
15481         done
15482 }
15483 run_test 154c "lfs path2fid and fid2path multiple arguments"
15484
15485 test_154d() {
15486         remote_mds_nodsh && skip "remote MDS with nodsh"
15487         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15488                 skip "Need MDS version at least 2.5.53"
15489
15490         if remote_mds; then
15491                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15492         else
15493                 nid="0@lo"
15494         fi
15495         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15496         local fd
15497         local cmd
15498
15499         rm -f $DIR/$tfile
15500         touch $DIR/$tfile
15501
15502         local fid=$($LFS path2fid $DIR/$tfile)
15503         # Open the file
15504         fd=$(free_fd)
15505         cmd="exec $fd<$DIR/$tfile"
15506         eval $cmd
15507         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15508         echo "$fid_list" | grep "$fid"
15509         rc=$?
15510
15511         cmd="exec $fd>/dev/null"
15512         eval $cmd
15513         if [ $rc -ne 0 ]; then
15514                 error "FID $fid not found in open files list $fid_list"
15515         fi
15516 }
15517 run_test 154d "Verify open file fid"
15518
15519 test_154e()
15520 {
15521         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15522                 skip "Need MDS version at least 2.6.50"
15523
15524         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15525                 error ".lustre returned by readdir"
15526         fi
15527 }
15528 run_test 154e ".lustre is not returned by readdir"
15529
15530 test_154f() {
15531         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15532
15533         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15534         mkdir_on_mdt0 $DIR/$tdir
15535         # test dirs inherit from its stripe
15536         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15537         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15538         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15539         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15540         touch $DIR/f
15541
15542         # get fid of parents
15543         local FID0=$($LFS path2fid $DIR/$tdir)
15544         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15545         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15546         local FID3=$($LFS path2fid $DIR)
15547
15548         # check that path2fid --parents returns expected <parent_fid>/name
15549         # 1) test for a directory (single parent)
15550         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15551         [ "$parent" == "$FID0/foo1" ] ||
15552                 error "expected parent: $FID0/foo1, got: $parent"
15553
15554         # 2) test for a file with nlink > 1 (multiple parents)
15555         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15556         echo "$parent" | grep -F "$FID1/$tfile" ||
15557                 error "$FID1/$tfile not returned in parent list"
15558         echo "$parent" | grep -F "$FID2/link" ||
15559                 error "$FID2/link not returned in parent list"
15560
15561         # 3) get parent by fid
15562         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15563         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15564         echo "$parent" | grep -F "$FID1/$tfile" ||
15565                 error "$FID1/$tfile not returned in parent list (by fid)"
15566         echo "$parent" | grep -F "$FID2/link" ||
15567                 error "$FID2/link not returned in parent list (by fid)"
15568
15569         # 4) test for entry in root directory
15570         parent=$($LFS path2fid --parents $DIR/f)
15571         echo "$parent" | grep -F "$FID3/f" ||
15572                 error "$FID3/f not returned in parent list"
15573
15574         # 5) test it on root directory
15575         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15576                 error "$MOUNT should not have parents"
15577
15578         # enable xattr caching and check that linkea is correctly updated
15579         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15580         save_lustre_params client "llite.*.xattr_cache" > $save
15581         lctl set_param llite.*.xattr_cache 1
15582
15583         # 6.1) linkea update on rename
15584         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15585
15586         # get parents by fid
15587         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15588         # foo1 should no longer be returned in parent list
15589         echo "$parent" | grep -F "$FID1" &&
15590                 error "$FID1 should no longer be in parent list"
15591         # the new path should appear
15592         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15593                 error "$FID2/$tfile.moved is not in parent list"
15594
15595         # 6.2) linkea update on unlink
15596         rm -f $DIR/$tdir/foo2/link
15597         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15598         # foo2/link should no longer be returned in parent list
15599         echo "$parent" | grep -F "$FID2/link" &&
15600                 error "$FID2/link should no longer be in parent list"
15601         true
15602
15603         rm -f $DIR/f
15604         restore_lustre_params < $save
15605         rm -f $save
15606 }
15607 run_test 154f "get parent fids by reading link ea"
15608
15609 test_154g()
15610 {
15611         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15612         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15613            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15614                 skip "Need MDS version at least 2.6.92"
15615
15616         mkdir_on_mdt0 $DIR/$tdir
15617         llapi_fid_test -d $DIR/$tdir
15618 }
15619 run_test 154g "various llapi FID tests"
15620
15621 test_155_small_load() {
15622     local temp=$TMP/$tfile
15623     local file=$DIR/$tfile
15624
15625     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15626         error "dd of=$temp bs=6096 count=1 failed"
15627     cp $temp $file
15628     cancel_lru_locks $OSC
15629     cmp $temp $file || error "$temp $file differ"
15630
15631     $TRUNCATE $temp 6000
15632     $TRUNCATE $file 6000
15633     cmp $temp $file || error "$temp $file differ (truncate1)"
15634
15635     echo "12345" >>$temp
15636     echo "12345" >>$file
15637     cmp $temp $file || error "$temp $file differ (append1)"
15638
15639     echo "12345" >>$temp
15640     echo "12345" >>$file
15641     cmp $temp $file || error "$temp $file differ (append2)"
15642
15643     rm -f $temp $file
15644     true
15645 }
15646
15647 test_155_big_load() {
15648         remote_ost_nodsh && skip "remote OST with nodsh"
15649
15650         local temp=$TMP/$tfile
15651         local file=$DIR/$tfile
15652
15653         free_min_max
15654         local cache_size=$(do_facet ost$((MAXI+1)) \
15655                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15656
15657         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15658         # pre-set value
15659         if [ -z "$cache_size" ]; then
15660                 cache_size=256
15661         fi
15662         local large_file_size=$((cache_size * 2))
15663
15664         echo "OSS cache size: $cache_size KB"
15665         echo "Large file size: $large_file_size KB"
15666
15667         [ $MAXV -le $large_file_size ] &&
15668                 skip_env "max available OST size needs > $large_file_size KB"
15669
15670         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15671
15672         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15673                 error "dd of=$temp bs=$large_file_size count=1k failed"
15674         cp $temp $file
15675         ls -lh $temp $file
15676         cancel_lru_locks osc
15677         cmp $temp $file || error "$temp $file differ"
15678
15679         rm -f $temp $file
15680         true
15681 }
15682
15683 save_writethrough() {
15684         local facets=$(get_facets OST)
15685
15686         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15687 }
15688
15689 test_155a() {
15690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15691
15692         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15693
15694         save_writethrough $p
15695
15696         set_cache read on
15697         set_cache writethrough on
15698         test_155_small_load
15699         restore_lustre_params < $p
15700         rm -f $p
15701 }
15702 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15703
15704 test_155b() {
15705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15706
15707         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15708
15709         save_writethrough $p
15710
15711         set_cache read on
15712         set_cache writethrough off
15713         test_155_small_load
15714         restore_lustre_params < $p
15715         rm -f $p
15716 }
15717 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15718
15719 test_155c() {
15720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15721
15722         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15723
15724         save_writethrough $p
15725
15726         set_cache read off
15727         set_cache writethrough on
15728         test_155_small_load
15729         restore_lustre_params < $p
15730         rm -f $p
15731 }
15732 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15733
15734 test_155d() {
15735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15736
15737         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15738
15739         save_writethrough $p
15740
15741         set_cache read off
15742         set_cache writethrough off
15743         test_155_small_load
15744         restore_lustre_params < $p
15745         rm -f $p
15746 }
15747 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15748
15749 test_155e() {
15750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15751
15752         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15753
15754         save_writethrough $p
15755
15756         set_cache read on
15757         set_cache writethrough on
15758         test_155_big_load
15759         restore_lustre_params < $p
15760         rm -f $p
15761 }
15762 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15763
15764 test_155f() {
15765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15766
15767         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15768
15769         save_writethrough $p
15770
15771         set_cache read on
15772         set_cache writethrough off
15773         test_155_big_load
15774         restore_lustre_params < $p
15775         rm -f $p
15776 }
15777 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15778
15779 test_155g() {
15780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15781
15782         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15783
15784         save_writethrough $p
15785
15786         set_cache read off
15787         set_cache writethrough on
15788         test_155_big_load
15789         restore_lustre_params < $p
15790         rm -f $p
15791 }
15792 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15793
15794 test_155h() {
15795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15796
15797         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15798
15799         save_writethrough $p
15800
15801         set_cache read off
15802         set_cache writethrough off
15803         test_155_big_load
15804         restore_lustre_params < $p
15805         rm -f $p
15806 }
15807 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15808
15809 test_156() {
15810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15811         remote_ost_nodsh && skip "remote OST with nodsh"
15812         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15813                 skip "stats not implemented on old servers"
15814         [ "$ost1_FSTYPE" = "zfs" ] &&
15815                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15816
15817         local CPAGES=3
15818         local BEFORE
15819         local AFTER
15820         local file="$DIR/$tfile"
15821         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15822
15823         save_writethrough $p
15824         roc_hit_init
15825
15826         log "Turn on read and write cache"
15827         set_cache read on
15828         set_cache writethrough on
15829
15830         log "Write data and read it back."
15831         log "Read should be satisfied from the cache."
15832         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15833         BEFORE=$(roc_hit)
15834         cancel_lru_locks osc
15835         cat $file >/dev/null
15836         AFTER=$(roc_hit)
15837         if ! let "AFTER - BEFORE == CPAGES"; then
15838                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15839         else
15840                 log "cache hits: before: $BEFORE, after: $AFTER"
15841         fi
15842
15843         log "Read again; it should 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 == CPAGES"; then
15849                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15850         else
15851                 log "cache hits:: before: $BEFORE, after: $AFTER"
15852         fi
15853
15854         log "Turn off the read cache and turn on the write cache"
15855         set_cache read off
15856         set_cache writethrough on
15857
15858         log "Read again; it should be satisfied from the cache."
15859         BEFORE=$(roc_hit)
15860         cancel_lru_locks osc
15861         cat $file >/dev/null
15862         AFTER=$(roc_hit)
15863         if ! let "AFTER - BEFORE == CPAGES"; then
15864                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15865         else
15866                 log "cache hits:: before: $BEFORE, after: $AFTER"
15867         fi
15868
15869         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15870                 # > 2.12.56 uses pagecache if cached
15871                 log "Read again; it should not be satisfied from the cache."
15872                 BEFORE=$AFTER
15873                 cancel_lru_locks osc
15874                 cat $file >/dev/null
15875                 AFTER=$(roc_hit)
15876                 if ! let "AFTER - BEFORE == 0"; then
15877                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15878                 else
15879                         log "cache hits:: before: $BEFORE, after: $AFTER"
15880                 fi
15881         fi
15882
15883         log "Write data and read it back."
15884         log "Read should be satisfied from the cache."
15885         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15886         BEFORE=$(roc_hit)
15887         cancel_lru_locks osc
15888         cat $file >/dev/null
15889         AFTER=$(roc_hit)
15890         if ! let "AFTER - BEFORE == CPAGES"; then
15891                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15892         else
15893                 log "cache hits:: before: $BEFORE, after: $AFTER"
15894         fi
15895
15896         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15897                 # > 2.12.56 uses pagecache if cached
15898                 log "Read again; it should not be satisfied from the cache."
15899                 BEFORE=$AFTER
15900                 cancel_lru_locks osc
15901                 cat $file >/dev/null
15902                 AFTER=$(roc_hit)
15903                 if ! let "AFTER - BEFORE == 0"; then
15904                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15905                 else
15906                         log "cache hits:: before: $BEFORE, after: $AFTER"
15907                 fi
15908         fi
15909
15910         log "Turn off read and write cache"
15911         set_cache read off
15912         set_cache writethrough off
15913
15914         log "Write data and read it back"
15915         log "It should not be satisfied from the cache."
15916         rm -f $file
15917         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15918         cancel_lru_locks osc
15919         BEFORE=$(roc_hit)
15920         cat $file >/dev/null
15921         AFTER=$(roc_hit)
15922         if ! let "AFTER - BEFORE == 0"; then
15923                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15924         else
15925                 log "cache hits:: before: $BEFORE, after: $AFTER"
15926         fi
15927
15928         log "Turn on the read cache and turn off the write cache"
15929         set_cache read on
15930         set_cache writethrough off
15931
15932         log "Write data and read it back"
15933         log "It should not be satisfied from the cache."
15934         rm -f $file
15935         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15936         BEFORE=$(roc_hit)
15937         cancel_lru_locks osc
15938         cat $file >/dev/null
15939         AFTER=$(roc_hit)
15940         if ! let "AFTER - BEFORE == 0"; then
15941                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15942         else
15943                 log "cache hits:: before: $BEFORE, after: $AFTER"
15944         fi
15945
15946         log "Read again; it should be satisfied from the cache."
15947         BEFORE=$(roc_hit)
15948         cancel_lru_locks osc
15949         cat $file >/dev/null
15950         AFTER=$(roc_hit)
15951         if ! let "AFTER - BEFORE == CPAGES"; then
15952                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15953         else
15954                 log "cache hits:: before: $BEFORE, after: $AFTER"
15955         fi
15956
15957         restore_lustre_params < $p
15958         rm -f $p $file
15959 }
15960 run_test 156 "Verification of tunables"
15961
15962 test_160a() {
15963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15964         remote_mds_nodsh && skip "remote MDS with nodsh"
15965         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15966                 skip "Need MDS version at least 2.2.0"
15967
15968         changelog_register || error "changelog_register failed"
15969         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15970         changelog_users $SINGLEMDS | grep -q $cl_user ||
15971                 error "User $cl_user not found in changelog_users"
15972
15973         mkdir_on_mdt0 $DIR/$tdir
15974
15975         # change something
15976         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15977         changelog_clear 0 || error "changelog_clear failed"
15978         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15979         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15980         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15981         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15982         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15983         rm $DIR/$tdir/pics/desktop.jpg
15984
15985         echo "verifying changelog mask"
15986         changelog_chmask "-MKDIR"
15987         changelog_chmask "-CLOSE"
15988
15989         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15990         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15991
15992         changelog_chmask "+MKDIR"
15993         changelog_chmask "+CLOSE"
15994
15995         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15996         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15997
15998         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15999         CLOSES=$(changelog_dump | grep -c "CLOSE")
16000         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16001         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16002
16003         # verify contents
16004         echo "verifying target fid"
16005         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16006         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16007         [ "$fidc" == "$fidf" ] ||
16008                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16009         echo "verifying parent fid"
16010         # The FID returned from the Changelog may be the directory shard on
16011         # a different MDT, and not the FID returned by path2fid on the parent.
16012         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16013         # since this is what will matter when recreating this file in the tree.
16014         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16015         local pathp=$($LFS fid2path $MOUNT "$fidp")
16016         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16017                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16018
16019         echo "getting records for $cl_user"
16020         changelog_users $SINGLEMDS
16021         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16022         local nclr=3
16023         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16024                 error "changelog_clear failed"
16025         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16026         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16027         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16028                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16029
16030         local min0_rec=$(changelog_users $SINGLEMDS |
16031                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16032         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16033                           awk '{ print $1; exit; }')
16034
16035         changelog_dump | tail -n 5
16036         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16037         [ $first_rec == $((min0_rec + 1)) ] ||
16038                 error "first index should be $min0_rec + 1 not $first_rec"
16039
16040         # LU-3446 changelog index reset on MDT restart
16041         local cur_rec1=$(changelog_users $SINGLEMDS |
16042                          awk '/^current.index:/ { print $NF }')
16043         changelog_clear 0 ||
16044                 error "clear all changelog records for $cl_user failed"
16045         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16046         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16047                 error "Fail to start $SINGLEMDS"
16048         local cur_rec2=$(changelog_users $SINGLEMDS |
16049                          awk '/^current.index:/ { print $NF }')
16050         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16051         [ $cur_rec1 == $cur_rec2 ] ||
16052                 error "current index should be $cur_rec1 not $cur_rec2"
16053
16054         echo "verifying users from this test are deregistered"
16055         changelog_deregister || error "changelog_deregister failed"
16056         changelog_users $SINGLEMDS | grep -q $cl_user &&
16057                 error "User '$cl_user' still in changelog_users"
16058
16059         # lctl get_param -n mdd.*.changelog_users
16060         # current_index: 144
16061         # ID    index (idle seconds)
16062         # cl3   144   (2) mask=<list>
16063         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16064                 # this is the normal case where all users were deregistered
16065                 # make sure no new records are added when no users are present
16066                 local last_rec1=$(changelog_users $SINGLEMDS |
16067                                   awk '/^current.index:/ { print $NF }')
16068                 touch $DIR/$tdir/chloe
16069                 local last_rec2=$(changelog_users $SINGLEMDS |
16070                                   awk '/^current.index:/ { print $NF }')
16071                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16072                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16073         else
16074                 # any changelog users must be leftovers from a previous test
16075                 changelog_users $SINGLEMDS
16076                 echo "other changelog users; can't verify off"
16077         fi
16078 }
16079 run_test 160a "changelog sanity"
16080
16081 test_160b() { # LU-3587
16082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16083         remote_mds_nodsh && skip "remote MDS with nodsh"
16084         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16085                 skip "Need MDS version at least 2.2.0"
16086
16087         changelog_register || error "changelog_register failed"
16088         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16089         changelog_users $SINGLEMDS | grep -q $cl_user ||
16090                 error "User '$cl_user' not found in changelog_users"
16091
16092         local longname1=$(str_repeat a 255)
16093         local longname2=$(str_repeat b 255)
16094
16095         cd $DIR
16096         echo "creating very long named file"
16097         touch $longname1 || error "create of '$longname1' failed"
16098         echo "renaming very long named file"
16099         mv $longname1 $longname2
16100
16101         changelog_dump | grep RENME | tail -n 5
16102         rm -f $longname2
16103 }
16104 run_test 160b "Verify that very long rename doesn't crash in changelog"
16105
16106 test_160c() {
16107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16108         remote_mds_nodsh && skip "remote MDS with nodsh"
16109
16110         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16111                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16112                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16113                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16114
16115         local rc=0
16116
16117         # Registration step
16118         changelog_register || error "changelog_register failed"
16119
16120         rm -rf $DIR/$tdir
16121         mkdir -p $DIR/$tdir
16122         $MCREATE $DIR/$tdir/foo_160c
16123         changelog_chmask "-TRUNC"
16124         $TRUNCATE $DIR/$tdir/foo_160c 200
16125         changelog_chmask "+TRUNC"
16126         $TRUNCATE $DIR/$tdir/foo_160c 199
16127         changelog_dump | tail -n 5
16128         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16129         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16130 }
16131 run_test 160c "verify that changelog log catch the truncate event"
16132
16133 test_160d() {
16134         remote_mds_nodsh && skip "remote MDS with nodsh"
16135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16137         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16138                 skip "Need MDS version at least 2.7.60"
16139
16140         # Registration step
16141         changelog_register || error "changelog_register failed"
16142
16143         mkdir -p $DIR/$tdir/migrate_dir
16144         changelog_clear 0 || error "changelog_clear failed"
16145
16146         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16147         changelog_dump | tail -n 5
16148         local migrates=$(changelog_dump | grep -c "MIGRT")
16149         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16150 }
16151 run_test 160d "verify that changelog log catch the migrate event"
16152
16153 test_160e() {
16154         remote_mds_nodsh && skip "remote MDS with nodsh"
16155
16156         # Create a user
16157         changelog_register || error "changelog_register failed"
16158
16159         local MDT0=$(facet_svc $SINGLEMDS)
16160         local rc
16161
16162         # No user (expect fail)
16163         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16164         rc=$?
16165         if [ $rc -eq 0 ]; then
16166                 error "Should fail without user"
16167         elif [ $rc -ne 4 ]; then
16168                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16169         fi
16170
16171         # Delete a future user (expect fail)
16172         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16173         rc=$?
16174         if [ $rc -eq 0 ]; then
16175                 error "Deleted non-existant user cl77"
16176         elif [ $rc -ne 2 ]; then
16177                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16178         fi
16179
16180         # Clear to a bad index (1 billion should be safe)
16181         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16182         rc=$?
16183
16184         if [ $rc -eq 0 ]; then
16185                 error "Successfully cleared to invalid CL index"
16186         elif [ $rc -ne 22 ]; then
16187                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16188         fi
16189 }
16190 run_test 160e "changelog negative testing (should return errors)"
16191
16192 test_160f() {
16193         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16194         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16195                 skip "Need MDS version at least 2.10.56"
16196
16197         local mdts=$(comma_list $(mdts_nodes))
16198
16199         # Create a user
16200         changelog_register || error "first changelog_register failed"
16201         changelog_register || error "second changelog_register failed"
16202         local cl_users
16203         declare -A cl_user1
16204         declare -A cl_user2
16205         local user_rec1
16206         local user_rec2
16207         local i
16208
16209         # generate some changelog records to accumulate on each MDT
16210         # use all_char because created files should be evenly distributed
16211         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16212                 error "test_mkdir $tdir failed"
16213         log "$(date +%s): creating first files"
16214         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16215                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16216                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16217         done
16218
16219         # check changelogs have been generated
16220         local start=$SECONDS
16221         local idle_time=$((MDSCOUNT * 5 + 5))
16222         local nbcl=$(changelog_dump | wc -l)
16223         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16224
16225         for param in "changelog_max_idle_time=$idle_time" \
16226                      "changelog_gc=1" \
16227                      "changelog_min_gc_interval=2" \
16228                      "changelog_min_free_cat_entries=3"; do
16229                 local MDT0=$(facet_svc $SINGLEMDS)
16230                 local var="${param%=*}"
16231                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16232
16233                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16234                 do_nodes $mdts $LCTL set_param mdd.*.$param
16235         done
16236
16237         # force cl_user2 to be idle (1st part), but also cancel the
16238         # cl_user1 records so that it is not evicted later in the test.
16239         local sleep1=$((idle_time / 2))
16240         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16241         sleep $sleep1
16242
16243         # simulate changelog catalog almost full
16244         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16245         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16246
16247         for i in $(seq $MDSCOUNT); do
16248                 cl_users=(${CL_USERS[mds$i]})
16249                 cl_user1[mds$i]="${cl_users[0]}"
16250                 cl_user2[mds$i]="${cl_users[1]}"
16251
16252                 [ -n "${cl_user1[mds$i]}" ] ||
16253                         error "mds$i: no user registered"
16254                 [ -n "${cl_user2[mds$i]}" ] ||
16255                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16256
16257                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16258                 [ -n "$user_rec1" ] ||
16259                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16260                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16261                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16262                 [ -n "$user_rec2" ] ||
16263                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16264                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16265                      "$user_rec1 + 2 == $user_rec2"
16266                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16267                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16268                               "$user_rec1 + 2, but is $user_rec2"
16269                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16270                 [ -n "$user_rec2" ] ||
16271                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16272                 [ $user_rec1 == $user_rec2 ] ||
16273                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16274                               "$user_rec1, but is $user_rec2"
16275         done
16276
16277         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16278         local sleep2=$((idle_time - (SECONDS - start) + 1))
16279         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16280         sleep $sleep2
16281
16282         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16283         # cl_user1 should be OK because it recently processed records.
16284         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16285         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16286                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16287                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16288         done
16289
16290         # ensure gc thread is done
16291         for i in $(mdts_nodes); do
16292                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16293                         error "$i: GC-thread not done"
16294         done
16295
16296         local first_rec
16297         for (( i = 1; i <= MDSCOUNT; i++ )); do
16298                 # check cl_user1 still registered
16299                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16300                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16301                 # check cl_user2 unregistered
16302                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16303                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16304
16305                 # check changelogs are present and starting at $user_rec1 + 1
16306                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16307                 [ -n "$user_rec1" ] ||
16308                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16309                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16310                             awk '{ print $1; exit; }')
16311
16312                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16313                 [ $((user_rec1 + 1)) == $first_rec ] ||
16314                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16315         done
16316 }
16317 run_test 160f "changelog garbage collect (timestamped users)"
16318
16319 test_160g() {
16320         remote_mds_nodsh && skip "remote MDS with nodsh"
16321         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16322                 skip "Need MDS version at least 2.14.55"
16323
16324         local mdts=$(comma_list $(mdts_nodes))
16325
16326         # Create a user
16327         changelog_register || error "first changelog_register failed"
16328         changelog_register || error "second changelog_register failed"
16329         local cl_users
16330         declare -A cl_user1
16331         declare -A cl_user2
16332         local user_rec1
16333         local user_rec2
16334         local i
16335
16336         # generate some changelog records to accumulate on each MDT
16337         # use all_char because created files should be evenly distributed
16338         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16339                 error "test_mkdir $tdir failed"
16340         for ((i = 0; i < MDSCOUNT; i++)); do
16341                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16342                         error "create $DIR/$tdir/d$i.1 failed"
16343         done
16344
16345         # check changelogs have been generated
16346         local nbcl=$(changelog_dump | wc -l)
16347         (( $nbcl > 0 )) || error "no changelogs found"
16348
16349         # reduce the max_idle_indexes value to make sure we exceed it
16350         for param in "changelog_max_idle_indexes=2" \
16351                      "changelog_gc=1" \
16352                      "changelog_min_gc_interval=2"; do
16353                 local MDT0=$(facet_svc $SINGLEMDS)
16354                 local var="${param%=*}"
16355                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16356
16357                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16358                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16359                         error "unable to set mdd.*.$param"
16360         done
16361
16362         local start=$SECONDS
16363         for i in $(seq $MDSCOUNT); do
16364                 cl_users=(${CL_USERS[mds$i]})
16365                 cl_user1[mds$i]="${cl_users[0]}"
16366                 cl_user2[mds$i]="${cl_users[1]}"
16367
16368                 [ -n "${cl_user1[mds$i]}" ] ||
16369                         error "mds$i: user1 is not registered"
16370                 [ -n "${cl_user2[mds$i]}" ] ||
16371                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16372
16373                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16374                 [ -n "$user_rec1" ] ||
16375                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16376                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16377                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16378                 [ -n "$user_rec2" ] ||
16379                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16380                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16381                      "$user_rec1 + 2 == $user_rec2"
16382                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16383                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16384                               "expected $user_rec1 + 2, but is $user_rec2"
16385                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16386                 [ -n "$user_rec2" ] ||
16387                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16388                 [ $user_rec1 == $user_rec2 ] ||
16389                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16390                               "expected $user_rec1, but is $user_rec2"
16391         done
16392
16393         # ensure we are past the previous changelog_min_gc_interval set above
16394         local sleep2=$((start + 2 - SECONDS))
16395         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16396         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16397         # cl_user1 should be OK because it recently processed records.
16398         for ((i = 0; i < MDSCOUNT; i++)); do
16399                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16400                         error "create $DIR/$tdir/d$i.3 failed"
16401         done
16402
16403         # ensure gc thread is done
16404         for i in $(mdts_nodes); do
16405                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16406                         error "$i: GC-thread not done"
16407         done
16408
16409         local first_rec
16410         for (( i = 1; i <= MDSCOUNT; i++ )); do
16411                 # check cl_user1 still registered
16412                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16413                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16414                 # check cl_user2 unregistered
16415                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16416                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16417
16418                 # check changelogs are present and starting at $user_rec1 + 1
16419                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16420                 [ -n "$user_rec1" ] ||
16421                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16422                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16423                             awk '{ print $1; exit; }')
16424
16425                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16426                 [ $((user_rec1 + 1)) == $first_rec ] ||
16427                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16428         done
16429 }
16430 run_test 160g "changelog garbage collect on idle records"
16431
16432 test_160h() {
16433         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16434         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16435                 skip "Need MDS version at least 2.10.56"
16436
16437         local mdts=$(comma_list $(mdts_nodes))
16438
16439         # Create a user
16440         changelog_register || error "first changelog_register failed"
16441         changelog_register || error "second changelog_register failed"
16442         local cl_users
16443         declare -A cl_user1
16444         declare -A cl_user2
16445         local user_rec1
16446         local user_rec2
16447         local i
16448
16449         # generate some changelog records to accumulate on each MDT
16450         # use all_char because created files should be evenly distributed
16451         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16452                 error "test_mkdir $tdir failed"
16453         for ((i = 0; i < MDSCOUNT; i++)); do
16454                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16455                         error "create $DIR/$tdir/d$i.1 failed"
16456         done
16457
16458         # check changelogs have been generated
16459         local nbcl=$(changelog_dump | wc -l)
16460         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16461
16462         for param in "changelog_max_idle_time=10" \
16463                      "changelog_gc=1" \
16464                      "changelog_min_gc_interval=2"; do
16465                 local MDT0=$(facet_svc $SINGLEMDS)
16466                 local var="${param%=*}"
16467                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16468
16469                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16470                 do_nodes $mdts $LCTL set_param mdd.*.$param
16471         done
16472
16473         # force cl_user2 to be idle (1st part)
16474         sleep 9
16475
16476         for i in $(seq $MDSCOUNT); do
16477                 cl_users=(${CL_USERS[mds$i]})
16478                 cl_user1[mds$i]="${cl_users[0]}"
16479                 cl_user2[mds$i]="${cl_users[1]}"
16480
16481                 [ -n "${cl_user1[mds$i]}" ] ||
16482                         error "mds$i: no user registered"
16483                 [ -n "${cl_user2[mds$i]}" ] ||
16484                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16485
16486                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16487                 [ -n "$user_rec1" ] ||
16488                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16489                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16490                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16491                 [ -n "$user_rec2" ] ||
16492                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16493                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16494                      "$user_rec1 + 2 == $user_rec2"
16495                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16496                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16497                               "$user_rec1 + 2, but is $user_rec2"
16498                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16499                 [ -n "$user_rec2" ] ||
16500                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16501                 [ $user_rec1 == $user_rec2 ] ||
16502                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16503                               "$user_rec1, but is $user_rec2"
16504         done
16505
16506         # force cl_user2 to be idle (2nd part) and to reach
16507         # changelog_max_idle_time
16508         sleep 2
16509
16510         # force each GC-thread start and block then
16511         # one per MDT/MDD, set fail_val accordingly
16512         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16513         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16514
16515         # generate more changelogs to trigger fail_loc
16516         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16517                 error "create $DIR/$tdir/${tfile}bis failed"
16518
16519         # stop MDT to stop GC-thread, should be done in back-ground as it will
16520         # block waiting for the thread to be released and exit
16521         declare -A stop_pids
16522         for i in $(seq $MDSCOUNT); do
16523                 stop mds$i &
16524                 stop_pids[mds$i]=$!
16525         done
16526
16527         for i in $(mdts_nodes); do
16528                 local facet
16529                 local nb=0
16530                 local facets=$(facets_up_on_host $i)
16531
16532                 for facet in ${facets//,/ }; do
16533                         if [[ $facet == mds* ]]; then
16534                                 nb=$((nb + 1))
16535                         fi
16536                 done
16537                 # ensure each MDS's gc threads are still present and all in "R"
16538                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16539                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16540                         error "$i: expected $nb GC-thread"
16541                 wait_update $i \
16542                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16543                         "R" 20 ||
16544                         error "$i: GC-thread not found in R-state"
16545                 # check umounts of each MDT on MDS have reached kthread_stop()
16546                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16547                         error "$i: expected $nb umount"
16548                 wait_update $i \
16549                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16550                         error "$i: umount not found in D-state"
16551         done
16552
16553         # release all GC-threads
16554         do_nodes $mdts $LCTL set_param fail_loc=0
16555
16556         # wait for MDT stop to complete
16557         for i in $(seq $MDSCOUNT); do
16558                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16559         done
16560
16561         # XXX
16562         # may try to check if any orphan changelog records are present
16563         # via ldiskfs/zfs and llog_reader...
16564
16565         # re-start/mount MDTs
16566         for i in $(seq $MDSCOUNT); do
16567                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16568                         error "Fail to start mds$i"
16569         done
16570
16571         local first_rec
16572         for i in $(seq $MDSCOUNT); do
16573                 # check cl_user1 still registered
16574                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16575                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16576                 # check cl_user2 unregistered
16577                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16578                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16579
16580                 # check changelogs are present and starting at $user_rec1 + 1
16581                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16582                 [ -n "$user_rec1" ] ||
16583                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16584                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16585                             awk '{ print $1; exit; }')
16586
16587                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16588                 [ $((user_rec1 + 1)) == $first_rec ] ||
16589                         error "mds$i: first index should be $user_rec1 + 1, " \
16590                               "but is $first_rec"
16591         done
16592 }
16593 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16594               "during mount"
16595
16596 test_160i() {
16597
16598         local mdts=$(comma_list $(mdts_nodes))
16599
16600         changelog_register || error "first changelog_register failed"
16601
16602         # generate some changelog records to accumulate on each MDT
16603         # use all_char because created files should be evenly distributed
16604         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16605                 error "test_mkdir $tdir failed"
16606         for ((i = 0; i < MDSCOUNT; i++)); do
16607                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16608                         error "create $DIR/$tdir/d$i.1 failed"
16609         done
16610
16611         # check changelogs have been generated
16612         local nbcl=$(changelog_dump | wc -l)
16613         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16614
16615         # simulate race between register and unregister
16616         # XXX as fail_loc is set per-MDS, with DNE configs the race
16617         # simulation will only occur for one MDT per MDS and for the
16618         # others the normal race scenario will take place
16619         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16620         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16621         do_nodes $mdts $LCTL set_param fail_val=1
16622
16623         # unregister 1st user
16624         changelog_deregister &
16625         local pid1=$!
16626         # wait some time for deregister work to reach race rdv
16627         sleep 2
16628         # register 2nd user
16629         changelog_register || error "2nd user register failed"
16630
16631         wait $pid1 || error "1st user deregister failed"
16632
16633         local i
16634         local last_rec
16635         declare -A LAST_REC
16636         for i in $(seq $MDSCOUNT); do
16637                 if changelog_users mds$i | grep "^cl"; then
16638                         # make sure new records are added with one user present
16639                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16640                                           awk '/^current.index:/ { print $NF }')
16641                 else
16642                         error "mds$i has no user registered"
16643                 fi
16644         done
16645
16646         # generate more changelog records to accumulate on each MDT
16647         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16648                 error "create $DIR/$tdir/${tfile}bis failed"
16649
16650         for i in $(seq $MDSCOUNT); do
16651                 last_rec=$(changelog_users $SINGLEMDS |
16652                            awk '/^current.index:/ { print $NF }')
16653                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16654                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16655                         error "changelogs are off on mds$i"
16656         done
16657 }
16658 run_test 160i "changelog user register/unregister race"
16659
16660 test_160j() {
16661         remote_mds_nodsh && skip "remote MDS with nodsh"
16662         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16663                 skip "Need MDS version at least 2.12.56"
16664
16665         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16666         stack_trap "umount $MOUNT2" EXIT
16667
16668         changelog_register || error "first changelog_register failed"
16669         stack_trap "changelog_deregister" EXIT
16670
16671         # generate some changelog
16672         # use all_char because created files should be evenly distributed
16673         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16674                 error "mkdir $tdir failed"
16675         for ((i = 0; i < MDSCOUNT; i++)); do
16676                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16677                         error "create $DIR/$tdir/d$i.1 failed"
16678         done
16679
16680         # open the changelog device
16681         exec 3>/dev/changelog-$FSNAME-MDT0000
16682         stack_trap "exec 3>&-" EXIT
16683         exec 4</dev/changelog-$FSNAME-MDT0000
16684         stack_trap "exec 4<&-" EXIT
16685
16686         # umount the first lustre mount
16687         umount $MOUNT
16688         stack_trap "mount_client $MOUNT" EXIT
16689
16690         # read changelog, which may or may not fail, but should not crash
16691         cat <&4 >/dev/null
16692
16693         # clear changelog
16694         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16695         changelog_users $SINGLEMDS | grep -q $cl_user ||
16696                 error "User $cl_user not found in changelog_users"
16697
16698         printf 'clear:'$cl_user':0' >&3
16699 }
16700 run_test 160j "client can be umounted while its chanangelog is being used"
16701
16702 test_160k() {
16703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16704         remote_mds_nodsh && skip "remote MDS with nodsh"
16705
16706         mkdir -p $DIR/$tdir/1/1
16707
16708         changelog_register || error "changelog_register failed"
16709         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16710
16711         changelog_users $SINGLEMDS | grep -q $cl_user ||
16712                 error "User '$cl_user' not found in changelog_users"
16713 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16714         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16715         rmdir $DIR/$tdir/1/1 & sleep 1
16716         mkdir $DIR/$tdir/2
16717         touch $DIR/$tdir/2/2
16718         rm -rf $DIR/$tdir/2
16719
16720         wait
16721         sleep 4
16722
16723         changelog_dump | grep rmdir || error "rmdir not recorded"
16724 }
16725 run_test 160k "Verify that changelog records are not lost"
16726
16727 # Verifies that a file passed as a parameter has recently had an operation
16728 # performed on it that has generated an MTIME changelog which contains the
16729 # correct parent FID. As files might reside on a different MDT from the
16730 # parent directory in DNE configurations, the FIDs are translated to paths
16731 # before being compared, which should be identical
16732 compare_mtime_changelog() {
16733         local file="${1}"
16734         local mdtidx
16735         local mtime
16736         local cl_fid
16737         local pdir
16738         local dir
16739
16740         mdtidx=$($LFS getstripe --mdt-index $file)
16741         mdtidx=$(printf "%04x" $mdtidx)
16742
16743         # Obtain the parent FID from the MTIME changelog
16744         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16745         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16746
16747         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16748         [ -z "$cl_fid" ] && error "parent FID not present"
16749
16750         # Verify that the path for the parent FID is the same as the path for
16751         # the test directory
16752         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16753
16754         dir=$(dirname $1)
16755
16756         [[ "${pdir%/}" == "$dir" ]] ||
16757                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16758 }
16759
16760 test_160l() {
16761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16762
16763         remote_mds_nodsh && skip "remote MDS with nodsh"
16764         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16765                 skip "Need MDS version at least 2.13.55"
16766
16767         local cl_user
16768
16769         changelog_register || error "changelog_register failed"
16770         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16771
16772         changelog_users $SINGLEMDS | grep -q $cl_user ||
16773                 error "User '$cl_user' not found in changelog_users"
16774
16775         # Clear some types so that MTIME changelogs are generated
16776         changelog_chmask "-CREAT"
16777         changelog_chmask "-CLOSE"
16778
16779         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16780
16781         # Test CL_MTIME during setattr
16782         touch $DIR/$tdir/$tfile
16783         compare_mtime_changelog $DIR/$tdir/$tfile
16784
16785         # Test CL_MTIME during close
16786         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16787         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16788 }
16789 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16790
16791 test_160m() {
16792         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16793         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16794                 skip "Need MDS version at least 2.14.51"
16795         local cl_users
16796         local cl_user1
16797         local cl_user2
16798         local pid1
16799
16800         # Create a user
16801         changelog_register || error "first changelog_register failed"
16802         changelog_register || error "second changelog_register failed"
16803
16804         cl_users=(${CL_USERS[mds1]})
16805         cl_user1="${cl_users[0]}"
16806         cl_user2="${cl_users[1]}"
16807         # generate some changelog records to accumulate on MDT0
16808         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16809         createmany -m $DIR/$tdir/$tfile 50 ||
16810                 error "create $DIR/$tdir/$tfile failed"
16811         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16812         rm -f $DIR/$tdir
16813
16814         # check changelogs have been generated
16815         local nbcl=$(changelog_dump | wc -l)
16816         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16817
16818 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16819         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16820
16821         __changelog_clear mds1 $cl_user1 +10
16822         __changelog_clear mds1 $cl_user2 0 &
16823         pid1=$!
16824         sleep 2
16825         __changelog_clear mds1 $cl_user1 0 ||
16826                 error "fail to cancel record for $cl_user1"
16827         wait $pid1
16828         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16829 }
16830 run_test 160m "Changelog clear race"
16831
16832 test_160n() {
16833         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16834         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16835                 skip "Need MDS version at least 2.14.51"
16836         local cl_users
16837         local cl_user1
16838         local cl_user2
16839         local pid1
16840         local first_rec
16841         local last_rec=0
16842
16843         # Create a user
16844         changelog_register || error "first changelog_register failed"
16845
16846         cl_users=(${CL_USERS[mds1]})
16847         cl_user1="${cl_users[0]}"
16848
16849         # generate some changelog records to accumulate on MDT0
16850         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16851         first_rec=$(changelog_users $SINGLEMDS |
16852                         awk '/^current.index:/ { print $NF }')
16853         while (( last_rec < (( first_rec + 65000)) )); do
16854                 createmany -m $DIR/$tdir/$tfile 10000 ||
16855                         error "create $DIR/$tdir/$tfile failed"
16856
16857                 for i in $(seq 0 10000); do
16858                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16859                                 > /dev/null
16860                 done
16861
16862                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16863                         error "unlinkmany failed unlink"
16864                 last_rec=$(changelog_users $SINGLEMDS |
16865                         awk '/^current.index:/ { print $NF }')
16866                 echo last record $last_rec
16867                 (( last_rec == 0 )) && error "no changelog found"
16868         done
16869
16870 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16871         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16872
16873         __changelog_clear mds1 $cl_user1 0 &
16874         pid1=$!
16875         sleep 2
16876         __changelog_clear mds1 $cl_user1 0 ||
16877                 error "fail to cancel record for $cl_user1"
16878         wait $pid1
16879         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16880 }
16881 run_test 160n "Changelog destroy race"
16882
16883 test_160o() {
16884         local mdt="$(facet_svc $SINGLEMDS)"
16885
16886         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16887         remote_mds_nodsh && skip "remote MDS with nodsh"
16888         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16889                 skip "Need MDS version at least 2.14.52"
16890
16891         changelog_register --user test_160o -m unlnk+close+open ||
16892                 error "changelog_register failed"
16893
16894         do_facet $SINGLEMDS $LCTL --device $mdt \
16895                                 changelog_register -u "Tt3_-#" &&
16896                 error "bad symbols in name should fail"
16897
16898         do_facet $SINGLEMDS $LCTL --device $mdt \
16899                                 changelog_register -u test_160o &&
16900                 error "the same name registration should fail"
16901
16902         do_facet $SINGLEMDS $LCTL --device $mdt \
16903                         changelog_register -u test_160toolongname &&
16904                 error "too long name registration should fail"
16905
16906         changelog_chmask "MARK+HSM"
16907         lctl get_param mdd.*.changelog*mask
16908         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16909         changelog_users $SINGLEMDS | grep -q $cl_user ||
16910                 error "User $cl_user not found in changelog_users"
16911         #verify username
16912         echo $cl_user | grep -q test_160o ||
16913                 error "User $cl_user has no specific name 'test160o'"
16914
16915         # change something
16916         changelog_clear 0 || error "changelog_clear failed"
16917         # generate some changelog records to accumulate on MDT0
16918         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16919         touch $DIR/$tdir/$tfile                 # open 1
16920
16921         OPENS=$(changelog_dump | grep -c "OPEN")
16922         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16923
16924         # must be no MKDIR it wasn't set as user mask
16925         MKDIR=$(changelog_dump | grep -c "MKDIR")
16926         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16927
16928         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16929                                 mdd.$mdt.changelog_current_mask -n)
16930         # register maskless user
16931         changelog_register || error "changelog_register failed"
16932         # effective mask should be not changed because it is not minimal
16933         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16934                                 mdd.$mdt.changelog_current_mask -n)
16935         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16936         # set server mask to minimal value
16937         changelog_chmask "MARK"
16938         # check effective mask again, should be treated as DEFMASK now
16939         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16940                                 mdd.$mdt.changelog_current_mask -n)
16941         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16942
16943         do_facet $SINGLEMDS $LCTL --device $mdt \
16944                                 changelog_deregister -u test_160o ||
16945                 error "cannot deregister by name"
16946 }
16947 run_test 160o "changelog user name and mask"
16948
16949 test_160p() {
16950         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16951         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16952                 skip "Need MDS version at least 2.14.51"
16953         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16954         local cl_users
16955         local cl_user1
16956         local entry_count
16957
16958         # Create a user
16959         changelog_register || error "first changelog_register failed"
16960
16961         cl_users=(${CL_USERS[mds1]})
16962         cl_user1="${cl_users[0]}"
16963
16964         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16965         createmany -m $DIR/$tdir/$tfile 50 ||
16966                 error "create $DIR/$tdir/$tfile failed"
16967         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16968         rm -rf $DIR/$tdir
16969
16970         # check changelogs have been generated
16971         entry_count=$(changelog_dump | wc -l)
16972         ((entry_count != 0)) || error "no changelog entries found"
16973
16974         # remove changelog_users and check that orphan entries are removed
16975         stop mds1
16976         local dev=$(mdsdevname 1)
16977         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16978         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16979         entry_count=$(changelog_dump | wc -l)
16980         ((entry_count == 0)) ||
16981                 error "found $entry_count changelog entries, expected none"
16982 }
16983 run_test 160p "Changelog orphan cleanup with no users"
16984
16985 test_160q() {
16986         local mdt="$(facet_svc $SINGLEMDS)"
16987         local clu
16988
16989         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16990         remote_mds_nodsh && skip "remote MDS with nodsh"
16991         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16992                 skip "Need MDS version at least 2.14.54"
16993
16994         # set server mask to minimal value like server init does
16995         changelog_chmask "MARK"
16996         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16997                 error "changelog_register failed"
16998         # check effective mask again, should be treated as DEFMASK now
16999         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17000                                 mdd.$mdt.changelog_current_mask -n)
17001         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17002                 error "changelog_deregister failed"
17003         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17004 }
17005 run_test 160q "changelog effective mask is DEFMASK if not set"
17006
17007 test_160s() {
17008         remote_mds_nodsh && skip "remote MDS with nodsh"
17009         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17010                 skip "Need MDS version at least 2.14.55"
17011
17012         local mdts=$(comma_list $(mdts_nodes))
17013
17014         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17015         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17016                                        fail_val=$((24 * 3600 * 10))
17017
17018         # Create a user which is 10 days old
17019         changelog_register || error "first changelog_register failed"
17020         local cl_users
17021         declare -A cl_user1
17022         local i
17023
17024         # generate some changelog records to accumulate on each MDT
17025         # use all_char because created files should be evenly distributed
17026         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17027                 error "test_mkdir $tdir failed"
17028         for ((i = 0; i < MDSCOUNT; i++)); do
17029                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17030                         error "create $DIR/$tdir/d$i.1 failed"
17031         done
17032
17033         # check changelogs have been generated
17034         local nbcl=$(changelog_dump | wc -l)
17035         (( nbcl > 0 )) || error "no changelogs found"
17036
17037         # reduce the max_idle_indexes value to make sure we exceed it
17038         for param in "changelog_max_idle_indexes=2097446912" \
17039                      "changelog_max_idle_time=2592000" \
17040                      "changelog_gc=1" \
17041                      "changelog_min_gc_interval=2"; do
17042                 local MDT0=$(facet_svc $SINGLEMDS)
17043                 local var="${param%=*}"
17044                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17045
17046                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17047                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17048                         error "unable to set mdd.*.$param"
17049         done
17050
17051         local start=$SECONDS
17052         for i in $(seq $MDSCOUNT); do
17053                 cl_users=(${CL_USERS[mds$i]})
17054                 cl_user1[mds$i]="${cl_users[0]}"
17055
17056                 [[ -n "${cl_user1[mds$i]}" ]] ||
17057                         error "mds$i: no user registered"
17058         done
17059
17060         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17061         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17062
17063         # ensure we are past the previous changelog_min_gc_interval set above
17064         local sleep2=$((start + 2 - SECONDS))
17065         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17066
17067         # Generate one more changelog to trigger GC
17068         for ((i = 0; i < MDSCOUNT; i++)); do
17069                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17070                         error "create $DIR/$tdir/d$i.3 failed"
17071         done
17072
17073         # ensure gc thread is done
17074         for node in $(mdts_nodes); do
17075                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17076                         error "$node: GC-thread not done"
17077         done
17078
17079         do_nodes $mdts $LCTL set_param fail_loc=0
17080
17081         for (( i = 1; i <= MDSCOUNT; i++ )); do
17082                 # check cl_user1 is purged
17083                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17084                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17085         done
17086         return 0
17087 }
17088 run_test 160s "changelog garbage collect on idle records * time"
17089
17090 test_161a() {
17091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17092
17093         test_mkdir -c1 $DIR/$tdir
17094         cp /etc/hosts $DIR/$tdir/$tfile
17095         test_mkdir -c1 $DIR/$tdir/foo1
17096         test_mkdir -c1 $DIR/$tdir/foo2
17097         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17098         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17099         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17100         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17101         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17102         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17103                 $LFS fid2path $DIR $FID
17104                 error "bad link ea"
17105         fi
17106         # middle
17107         rm $DIR/$tdir/foo2/zachary
17108         # last
17109         rm $DIR/$tdir/foo2/thor
17110         # first
17111         rm $DIR/$tdir/$tfile
17112         # rename
17113         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17114         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17115                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17116         rm $DIR/$tdir/foo2/maggie
17117
17118         # overflow the EA
17119         local longname=$tfile.avg_len_is_thirty_two_
17120         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17121                 error_noexit 'failed to unlink many hardlinks'" EXIT
17122         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17123                 error "failed to hardlink many files"
17124         links=$($LFS fid2path $DIR $FID | wc -l)
17125         echo -n "${links}/1000 links in link EA"
17126         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17127 }
17128 run_test 161a "link ea sanity"
17129
17130 test_161b() {
17131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17132         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17133
17134         local MDTIDX=1
17135         local remote_dir=$DIR/$tdir/remote_dir
17136
17137         mkdir -p $DIR/$tdir
17138         $LFS mkdir -i $MDTIDX $remote_dir ||
17139                 error "create remote directory failed"
17140
17141         cp /etc/hosts $remote_dir/$tfile
17142         mkdir -p $remote_dir/foo1
17143         mkdir -p $remote_dir/foo2
17144         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17145         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17146         ln $remote_dir/$tfile $remote_dir/foo1/luna
17147         ln $remote_dir/$tfile $remote_dir/foo2/thor
17148
17149         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17150                      tr -d ']')
17151         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17152                 $LFS fid2path $DIR $FID
17153                 error "bad link ea"
17154         fi
17155         # middle
17156         rm $remote_dir/foo2/zachary
17157         # last
17158         rm $remote_dir/foo2/thor
17159         # first
17160         rm $remote_dir/$tfile
17161         # rename
17162         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17163         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17164         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17165                 $LFS fid2path $DIR $FID
17166                 error "bad link rename"
17167         fi
17168         rm $remote_dir/foo2/maggie
17169
17170         # overflow the EA
17171         local longname=filename_avg_len_is_thirty_two_
17172         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17173                 error "failed to hardlink many files"
17174         links=$($LFS fid2path $DIR $FID | wc -l)
17175         echo -n "${links}/1000 links in link EA"
17176         [[ ${links} -gt 60 ]] ||
17177                 error "expected at least 60 links in link EA"
17178         unlinkmany $remote_dir/foo2/$longname 1000 ||
17179         error "failed to unlink many hardlinks"
17180 }
17181 run_test 161b "link ea sanity under remote directory"
17182
17183 test_161c() {
17184         remote_mds_nodsh && skip "remote MDS with nodsh"
17185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17186         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17187                 skip "Need MDS version at least 2.1.5"
17188
17189         # define CLF_RENAME_LAST 0x0001
17190         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17191         changelog_register || error "changelog_register failed"
17192
17193         rm -rf $DIR/$tdir
17194         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17195         touch $DIR/$tdir/foo_161c
17196         touch $DIR/$tdir/bar_161c
17197         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17198         changelog_dump | grep RENME | tail -n 5
17199         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17200         changelog_clear 0 || error "changelog_clear failed"
17201         if [ x$flags != "x0x1" ]; then
17202                 error "flag $flags is not 0x1"
17203         fi
17204
17205         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17206         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17207         touch $DIR/$tdir/foo_161c
17208         touch $DIR/$tdir/bar_161c
17209         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17210         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17211         changelog_dump | grep RENME | tail -n 5
17212         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17213         changelog_clear 0 || error "changelog_clear failed"
17214         if [ x$flags != "x0x0" ]; then
17215                 error "flag $flags is not 0x0"
17216         fi
17217         echo "rename overwrite a target having nlink > 1," \
17218                 "changelog record has flags of $flags"
17219
17220         # rename doesn't overwrite a target (changelog flag 0x0)
17221         touch $DIR/$tdir/foo_161c
17222         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17223         changelog_dump | grep RENME | tail -n 5
17224         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17225         changelog_clear 0 || error "changelog_clear failed"
17226         if [ x$flags != "x0x0" ]; then
17227                 error "flag $flags is not 0x0"
17228         fi
17229         echo "rename doesn't overwrite a target," \
17230                 "changelog record has flags of $flags"
17231
17232         # define CLF_UNLINK_LAST 0x0001
17233         # unlink a file having nlink = 1 (changelog flag 0x1)
17234         rm -f $DIR/$tdir/foo2_161c
17235         changelog_dump | grep UNLNK | tail -n 5
17236         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17237         changelog_clear 0 || error "changelog_clear failed"
17238         if [ x$flags != "x0x1" ]; then
17239                 error "flag $flags is not 0x1"
17240         fi
17241         echo "unlink a file having nlink = 1," \
17242                 "changelog record has flags of $flags"
17243
17244         # unlink a file having nlink > 1 (changelog flag 0x0)
17245         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17246         rm -f $DIR/$tdir/foobar_161c
17247         changelog_dump | grep UNLNK | tail -n 5
17248         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17249         changelog_clear 0 || error "changelog_clear failed"
17250         if [ x$flags != "x0x0" ]; then
17251                 error "flag $flags is not 0x0"
17252         fi
17253         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17254 }
17255 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17256
17257 test_161d() {
17258         remote_mds_nodsh && skip "remote MDS with nodsh"
17259         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17260
17261         local pid
17262         local fid
17263
17264         changelog_register || error "changelog_register failed"
17265
17266         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17267         # interfer with $MOUNT/.lustre/fid/ access
17268         mkdir $DIR/$tdir
17269         [[ $? -eq 0 ]] || error "mkdir failed"
17270
17271         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17272         $LCTL set_param fail_loc=0x8000140c
17273         # 5s pause
17274         $LCTL set_param fail_val=5
17275
17276         # create file
17277         echo foofoo > $DIR/$tdir/$tfile &
17278         pid=$!
17279
17280         # wait for create to be delayed
17281         sleep 2
17282
17283         ps -p $pid
17284         [[ $? -eq 0 ]] || error "create should be blocked"
17285
17286         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17287         stack_trap "rm -f $tempfile"
17288         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17289         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17290         # some delay may occur during ChangeLog publishing and file read just
17291         # above, that could allow file write to happen finally
17292         [[ -s $tempfile ]] && echo "file should be empty"
17293
17294         $LCTL set_param fail_loc=0
17295
17296         wait $pid
17297         [[ $? -eq 0 ]] || error "create failed"
17298 }
17299 run_test 161d "create with concurrent .lustre/fid access"
17300
17301 check_path() {
17302         local expected="$1"
17303         shift
17304         local fid="$2"
17305
17306         local path
17307         path=$($LFS fid2path "$@")
17308         local rc=$?
17309
17310         if [ $rc -ne 0 ]; then
17311                 error "path looked up of '$expected' failed: rc=$rc"
17312         elif [ "$path" != "$expected" ]; then
17313                 error "path looked up '$path' instead of '$expected'"
17314         else
17315                 echo "FID '$fid' resolves to path '$path' as expected"
17316         fi
17317 }
17318
17319 test_162a() { # was test_162
17320         test_mkdir -p -c1 $DIR/$tdir/d2
17321         touch $DIR/$tdir/d2/$tfile
17322         touch $DIR/$tdir/d2/x1
17323         touch $DIR/$tdir/d2/x2
17324         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17325         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17326         # regular file
17327         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17328         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17329
17330         # softlink
17331         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17332         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17333         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17334
17335         # softlink to wrong file
17336         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17337         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17338         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17339
17340         # hardlink
17341         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17342         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17343         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17344         # fid2path dir/fsname should both work
17345         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17346         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17347
17348         # hardlink count: check that there are 2 links
17349         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17350         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17351
17352         # hardlink indexing: remove the first link
17353         rm $DIR/$tdir/d2/p/q/r/hlink
17354         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17355 }
17356 run_test 162a "path lookup sanity"
17357
17358 test_162b() {
17359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17361
17362         mkdir $DIR/$tdir
17363         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17364                                 error "create striped dir failed"
17365
17366         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17367                                         tail -n 1 | awk '{print $2}')
17368         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17369
17370         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17371         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17372
17373         # regular file
17374         for ((i=0;i<5;i++)); do
17375                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17376                         error "get fid for f$i failed"
17377                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17378
17379                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17380                         error "get fid for d$i failed"
17381                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17382         done
17383
17384         return 0
17385 }
17386 run_test 162b "striped directory path lookup sanity"
17387
17388 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17389 test_162c() {
17390         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17391                 skip "Need MDS version at least 2.7.51"
17392
17393         local lpath=$tdir.local
17394         local rpath=$tdir.remote
17395
17396         test_mkdir $DIR/$lpath
17397         test_mkdir $DIR/$rpath
17398
17399         for ((i = 0; i <= 101; i++)); do
17400                 lpath="$lpath/$i"
17401                 mkdir $DIR/$lpath
17402                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17403                         error "get fid for local directory $DIR/$lpath failed"
17404                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17405
17406                 rpath="$rpath/$i"
17407                 test_mkdir $DIR/$rpath
17408                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17409                         error "get fid for remote directory $DIR/$rpath failed"
17410                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17411         done
17412
17413         return 0
17414 }
17415 run_test 162c "fid2path works with paths 100 or more directories deep"
17416
17417 oalr_event_count() {
17418         local event="${1}"
17419         local trace="${2}"
17420
17421         awk -v name="${FSNAME}-OST0000" \
17422             -v event="${event}" \
17423             '$1 == "TRACE" && $2 == event && $3 == name' \
17424             "${trace}" |
17425         wc -l
17426 }
17427
17428 oalr_expect_event_count() {
17429         local event="${1}"
17430         local trace="${2}"
17431         local expect="${3}"
17432         local count
17433
17434         count=$(oalr_event_count "${event}" "${trace}")
17435         if ((count == expect)); then
17436                 return 0
17437         fi
17438
17439         error_noexit "${event} event count was '${count}', expected ${expect}"
17440         cat "${trace}" >&2
17441         exit 1
17442 }
17443
17444 cleanup_165() {
17445         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17446         stop ost1
17447         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17448 }
17449
17450 setup_165() {
17451         sync # Flush previous IOs so we can count log entries.
17452         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17453         stack_trap cleanup_165 EXIT
17454 }
17455
17456 test_165a() {
17457         local trace="/tmp/${tfile}.trace"
17458         local rc
17459         local count
17460
17461         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17462                 skip "OFD access log unsupported"
17463
17464         setup_165
17465         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17466         sleep 5
17467
17468         do_facet ost1 ofd_access_log_reader --list
17469         stop ost1
17470
17471         do_facet ost1 killall -TERM ofd_access_log_reader
17472         wait
17473         rc=$?
17474
17475         if ((rc != 0)); then
17476                 error "ofd_access_log_reader exited with rc = '${rc}'"
17477         fi
17478
17479         # Parse trace file for discovery events:
17480         oalr_expect_event_count alr_log_add "${trace}" 1
17481         oalr_expect_event_count alr_log_eof "${trace}" 1
17482         oalr_expect_event_count alr_log_free "${trace}" 1
17483 }
17484 run_test 165a "ofd access log discovery"
17485
17486 test_165b() {
17487         local trace="/tmp/${tfile}.trace"
17488         local file="${DIR}/${tfile}"
17489         local pfid1
17490         local pfid2
17491         local -a entry
17492         local rc
17493         local count
17494         local size
17495         local flags
17496
17497         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17498                 skip "OFD access log unsupported"
17499
17500         setup_165
17501         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17502         sleep 5
17503
17504         do_facet ost1 ofd_access_log_reader --list
17505
17506         lfs setstripe -c 1 -i 0 "${file}"
17507         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17508                 error "cannot create '${file}'"
17509
17510         sleep 5
17511         do_facet ost1 killall -TERM ofd_access_log_reader
17512         wait
17513         rc=$?
17514
17515         if ((rc != 0)); then
17516                 error "ofd_access_log_reader exited with rc = '${rc}'"
17517         fi
17518
17519         oalr_expect_event_count alr_log_entry "${trace}" 1
17520
17521         pfid1=$($LFS path2fid "${file}")
17522
17523         # 1     2             3   4    5     6   7    8    9     10
17524         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17525         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17526
17527         echo "entry = '${entry[*]}'" >&2
17528
17529         pfid2=${entry[4]}
17530         if [[ "${pfid1}" != "${pfid2}" ]]; then
17531                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17532         fi
17533
17534         size=${entry[8]}
17535         if ((size != 1048576)); then
17536                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17537         fi
17538
17539         flags=${entry[10]}
17540         if [[ "${flags}" != "w" ]]; then
17541                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17542         fi
17543
17544         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17545         sleep 5
17546
17547         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17548                 error "cannot read '${file}'"
17549         sleep 5
17550
17551         do_facet ost1 killall -TERM ofd_access_log_reader
17552         wait
17553         rc=$?
17554
17555         if ((rc != 0)); then
17556                 error "ofd_access_log_reader exited with rc = '${rc}'"
17557         fi
17558
17559         oalr_expect_event_count alr_log_entry "${trace}" 1
17560
17561         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17562         echo "entry = '${entry[*]}'" >&2
17563
17564         pfid2=${entry[4]}
17565         if [[ "${pfid1}" != "${pfid2}" ]]; then
17566                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17567         fi
17568
17569         size=${entry[8]}
17570         if ((size != 524288)); then
17571                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17572         fi
17573
17574         flags=${entry[10]}
17575         if [[ "${flags}" != "r" ]]; then
17576                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17577         fi
17578 }
17579 run_test 165b "ofd access log entries are produced and consumed"
17580
17581 test_165c() {
17582         local trace="/tmp/${tfile}.trace"
17583         local file="${DIR}/${tdir}/${tfile}"
17584
17585         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17586                 skip "OFD access log unsupported"
17587
17588         test_mkdir "${DIR}/${tdir}"
17589
17590         setup_165
17591         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17592         sleep 5
17593
17594         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17595
17596         # 4096 / 64 = 64. Create twice as many entries.
17597         for ((i = 0; i < 128; i++)); do
17598                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17599                         error "cannot create file"
17600         done
17601
17602         sync
17603
17604         do_facet ost1 killall -TERM ofd_access_log_reader
17605         wait
17606         rc=$?
17607         if ((rc != 0)); then
17608                 error "ofd_access_log_reader exited with rc = '${rc}'"
17609         fi
17610
17611         unlinkmany  "${file}-%d" 128
17612 }
17613 run_test 165c "full ofd access logs do not block IOs"
17614
17615 oal_get_read_count() {
17616         local stats="$1"
17617
17618         # STATS lustre-OST0001 alr_read_count 1
17619
17620         do_facet ost1 cat "${stats}" |
17621         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17622              END { print count; }'
17623 }
17624
17625 oal_expect_read_count() {
17626         local stats="$1"
17627         local count
17628         local expect="$2"
17629
17630         # Ask ofd_access_log_reader to write stats.
17631         do_facet ost1 killall -USR1 ofd_access_log_reader
17632
17633         # Allow some time for things to happen.
17634         sleep 1
17635
17636         count=$(oal_get_read_count "${stats}")
17637         if ((count == expect)); then
17638                 return 0
17639         fi
17640
17641         error_noexit "bad read count, got ${count}, expected ${expect}"
17642         do_facet ost1 cat "${stats}" >&2
17643         exit 1
17644 }
17645
17646 test_165d() {
17647         local stats="/tmp/${tfile}.stats"
17648         local file="${DIR}/${tdir}/${tfile}"
17649         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17650
17651         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17652                 skip "OFD access log unsupported"
17653
17654         test_mkdir "${DIR}/${tdir}"
17655
17656         setup_165
17657         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17658         sleep 5
17659
17660         lfs setstripe -c 1 -i 0 "${file}"
17661
17662         do_facet ost1 lctl set_param "${param}=rw"
17663         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17664                 error "cannot create '${file}'"
17665         oal_expect_read_count "${stats}" 1
17666
17667         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17668                 error "cannot read '${file}'"
17669         oal_expect_read_count "${stats}" 2
17670
17671         do_facet ost1 lctl set_param "${param}=r"
17672         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17673                 error "cannot create '${file}'"
17674         oal_expect_read_count "${stats}" 2
17675
17676         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17677                 error "cannot read '${file}'"
17678         oal_expect_read_count "${stats}" 3
17679
17680         do_facet ost1 lctl set_param "${param}=w"
17681         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17682                 error "cannot create '${file}'"
17683         oal_expect_read_count "${stats}" 4
17684
17685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17686                 error "cannot read '${file}'"
17687         oal_expect_read_count "${stats}" 4
17688
17689         do_facet ost1 lctl set_param "${param}=0"
17690         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17691                 error "cannot create '${file}'"
17692         oal_expect_read_count "${stats}" 4
17693
17694         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17695                 error "cannot read '${file}'"
17696         oal_expect_read_count "${stats}" 4
17697
17698         do_facet ost1 killall -TERM ofd_access_log_reader
17699         wait
17700         rc=$?
17701         if ((rc != 0)); then
17702                 error "ofd_access_log_reader exited with rc = '${rc}'"
17703         fi
17704 }
17705 run_test 165d "ofd_access_log mask works"
17706
17707 test_165e() {
17708         local stats="/tmp/${tfile}.stats"
17709         local file0="${DIR}/${tdir}-0/${tfile}"
17710         local file1="${DIR}/${tdir}-1/${tfile}"
17711
17712         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17713                 skip "OFD access log unsupported"
17714
17715         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17716
17717         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17718         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17719
17720         lfs setstripe -c 1 -i 0 "${file0}"
17721         lfs setstripe -c 1 -i 0 "${file1}"
17722
17723         setup_165
17724         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17725         sleep 5
17726
17727         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17728                 error "cannot create '${file0}'"
17729         sync
17730         oal_expect_read_count "${stats}" 0
17731
17732         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17733                 error "cannot create '${file1}'"
17734         sync
17735         oal_expect_read_count "${stats}" 1
17736
17737         do_facet ost1 killall -TERM ofd_access_log_reader
17738         wait
17739         rc=$?
17740         if ((rc != 0)); then
17741                 error "ofd_access_log_reader exited with rc = '${rc}'"
17742         fi
17743 }
17744 run_test 165e "ofd_access_log MDT index filter works"
17745
17746 test_165f() {
17747         local trace="/tmp/${tfile}.trace"
17748         local rc
17749         local count
17750
17751         setup_165
17752         do_facet ost1 timeout 60 ofd_access_log_reader \
17753                 --exit-on-close --debug=- --trace=- > "${trace}" &
17754         sleep 5
17755         stop ost1
17756
17757         wait
17758         rc=$?
17759
17760         if ((rc != 0)); then
17761                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17762                 cat "${trace}"
17763                 exit 1
17764         fi
17765 }
17766 run_test 165f "ofd_access_log_reader --exit-on-close works"
17767
17768 test_169() {
17769         # do directio so as not to populate the page cache
17770         log "creating a 10 Mb file"
17771         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17772                 error "multiop failed while creating a file"
17773         log "starting reads"
17774         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17775         log "truncating the file"
17776         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17777                 error "multiop failed while truncating the file"
17778         log "killing dd"
17779         kill %+ || true # reads might have finished
17780         echo "wait until dd is finished"
17781         wait
17782         log "removing the temporary file"
17783         rm -rf $DIR/$tfile || error "tmp file removal failed"
17784 }
17785 run_test 169 "parallel read and truncate should not deadlock"
17786
17787 test_170() {
17788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17789
17790         $LCTL clear     # bug 18514
17791         $LCTL debug_daemon start $TMP/${tfile}_log_good
17792         touch $DIR/$tfile
17793         $LCTL debug_daemon stop
17794         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17795                 error "sed failed to read log_good"
17796
17797         $LCTL debug_daemon start $TMP/${tfile}_log_good
17798         rm -rf $DIR/$tfile
17799         $LCTL debug_daemon stop
17800
17801         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17802                error "lctl df log_bad failed"
17803
17804         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17805         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17806
17807         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17808         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17809
17810         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17811                 error "bad_line good_line1 good_line2 are empty"
17812
17813         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17814         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17815         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17816
17817         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17818         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17819         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17820
17821         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17822                 error "bad_line_new good_line_new are empty"
17823
17824         local expected_good=$((good_line1 + good_line2*2))
17825
17826         rm -f $TMP/${tfile}*
17827         # LU-231, short malformed line may not be counted into bad lines
17828         if [ $bad_line -ne $bad_line_new ] &&
17829                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17830                 error "expected $bad_line bad lines, but got $bad_line_new"
17831                 return 1
17832         fi
17833
17834         if [ $expected_good -ne $good_line_new ]; then
17835                 error "expected $expected_good good lines, but got $good_line_new"
17836                 return 2
17837         fi
17838         true
17839 }
17840 run_test 170 "test lctl df to handle corrupted log ====================="
17841
17842 test_171() { # bug20592
17843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17844
17845         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17846         $LCTL set_param fail_loc=0x50e
17847         $LCTL set_param fail_val=3000
17848         multiop_bg_pause $DIR/$tfile O_s || true
17849         local MULTIPID=$!
17850         kill -USR1 $MULTIPID
17851         # cause log dump
17852         sleep 3
17853         wait $MULTIPID
17854         if dmesg | grep "recursive fault"; then
17855                 error "caught a recursive fault"
17856         fi
17857         $LCTL set_param fail_loc=0
17858         true
17859 }
17860 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17861
17862 test_172() {
17863
17864         #define OBD_FAIL_OBD_CLEANUP  0x60e
17865         $LCTL set_param fail_loc=0x60e
17866         umount $MOUNT || error "umount $MOUNT failed"
17867         stack_trap "mount_client $MOUNT"
17868
17869         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17870                 error "no client OBDs are remained"
17871
17872         $LCTL dl | while read devno state type name foo; do
17873                 case $type in
17874                 lov|osc|lmv|mdc)
17875                         $LCTL --device $name cleanup
17876                         $LCTL --device $name detach
17877                         ;;
17878                 *)
17879                         # skip server devices
17880                         ;;
17881                 esac
17882         done
17883
17884         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17885                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17886                 error "some client OBDs are still remained"
17887         fi
17888
17889 }
17890 run_test 172 "manual device removal with lctl cleanup/detach ======"
17891
17892 # it would be good to share it with obdfilter-survey/iokit-libecho code
17893 setup_obdecho_osc () {
17894         local rc=0
17895         local ost_nid=$1
17896         local obdfilter_name=$2
17897         echo "Creating new osc for $obdfilter_name on $ost_nid"
17898         # make sure we can find loopback nid
17899         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17900
17901         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17902                            ${obdfilter_name}_osc_UUID || rc=2; }
17903         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17904                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17905         return $rc
17906 }
17907
17908 cleanup_obdecho_osc () {
17909         local obdfilter_name=$1
17910         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17911         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17912         return 0
17913 }
17914
17915 obdecho_test() {
17916         local OBD=$1
17917         local node=$2
17918         local pages=${3:-64}
17919         local rc=0
17920         local id
17921
17922         local count=10
17923         local obd_size=$(get_obd_size $node $OBD)
17924         local page_size=$(get_page_size $node)
17925         if [[ -n "$obd_size" ]]; then
17926                 local new_count=$((obd_size / (pages * page_size / 1024)))
17927                 [[ $new_count -ge $count ]] || count=$new_count
17928         fi
17929
17930         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17931         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17932                            rc=2; }
17933         if [ $rc -eq 0 ]; then
17934             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17935             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17936         fi
17937         echo "New object id is $id"
17938         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17939                            rc=4; }
17940         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17941                            "test_brw $count w v $pages $id" || rc=4; }
17942         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17943                            rc=4; }
17944         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17945                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17946         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17947                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17948         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17949         return $rc
17950 }
17951
17952 test_180a() {
17953         skip "obdecho on osc is no longer supported"
17954 }
17955 run_test 180a "test obdecho on osc"
17956
17957 test_180b() {
17958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17959         remote_ost_nodsh && skip "remote OST with nodsh"
17960
17961         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17962                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17963                 error "failed to load module obdecho"
17964
17965         local target=$(do_facet ost1 $LCTL dl |
17966                        awk '/obdfilter/ { print $4; exit; }')
17967
17968         if [ -n "$target" ]; then
17969                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17970         else
17971                 do_facet ost1 $LCTL dl
17972                 error "there is no obdfilter target on ost1"
17973         fi
17974 }
17975 run_test 180b "test obdecho directly on obdfilter"
17976
17977 test_180c() { # LU-2598
17978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17979         remote_ost_nodsh && skip "remote OST with nodsh"
17980         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17981                 skip "Need MDS version at least 2.4.0"
17982
17983         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17984                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17985                 error "failed to load module obdecho"
17986
17987         local target=$(do_facet ost1 $LCTL dl |
17988                        awk '/obdfilter/ { print $4; exit; }')
17989
17990         if [ -n "$target" ]; then
17991                 local pages=16384 # 64MB bulk I/O RPC size
17992
17993                 obdecho_test "$target" ost1 "$pages" ||
17994                         error "obdecho_test with pages=$pages failed with $?"
17995         else
17996                 do_facet ost1 $LCTL dl
17997                 error "there is no obdfilter target on ost1"
17998         fi
17999 }
18000 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18001
18002 test_181() { # bug 22177
18003         test_mkdir $DIR/$tdir
18004         # create enough files to index the directory
18005         createmany -o $DIR/$tdir/foobar 4000
18006         # print attributes for debug purpose
18007         lsattr -d .
18008         # open dir
18009         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18010         MULTIPID=$!
18011         # remove the files & current working dir
18012         unlinkmany $DIR/$tdir/foobar 4000
18013         rmdir $DIR/$tdir
18014         kill -USR1 $MULTIPID
18015         wait $MULTIPID
18016         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18017         return 0
18018 }
18019 run_test 181 "Test open-unlinked dir ========================"
18020
18021 test_182a() {
18022         local fcount=1000
18023         local tcount=10
18024
18025         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18026
18027         $LCTL set_param mdc.*.rpc_stats=clear
18028
18029         for (( i = 0; i < $tcount; i++ )) ; do
18030                 mkdir $DIR/$tdir/$i
18031         done
18032
18033         for (( i = 0; i < $tcount; i++ )) ; do
18034                 createmany -o $DIR/$tdir/$i/f- $fcount &
18035         done
18036         wait
18037
18038         for (( i = 0; i < $tcount; i++ )) ; do
18039                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18040         done
18041         wait
18042
18043         $LCTL get_param mdc.*.rpc_stats
18044
18045         rm -rf $DIR/$tdir
18046 }
18047 run_test 182a "Test parallel modify metadata operations from mdc"
18048
18049 test_182b() {
18050         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18051         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18052         local dcount=1000
18053         local tcount=10
18054         local stime
18055         local etime
18056         local delta
18057
18058         do_facet mds1 $LCTL list_param \
18059                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18060                 skip "MDS lacks parallel RPC handling"
18061
18062         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18063
18064         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18065                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18066
18067         stime=$(date +%s)
18068         createmany -i 0 -d $DIR/$tdir/t- $tcount
18069
18070         for (( i = 0; i < $tcount; i++ )) ; do
18071                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18072         done
18073         wait
18074         etime=$(date +%s)
18075         delta=$((etime - stime))
18076         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18077
18078         stime=$(date +%s)
18079         for (( i = 0; i < $tcount; i++ )) ; do
18080                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18081         done
18082         wait
18083         etime=$(date +%s)
18084         delta=$((etime - stime))
18085         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18086
18087         rm -rf $DIR/$tdir
18088
18089         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18090
18091         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18092
18093         stime=$(date +%s)
18094         createmany -i 0 -d $DIR/$tdir/t- $tcount
18095
18096         for (( i = 0; i < $tcount; i++ )) ; do
18097                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18098         done
18099         wait
18100         etime=$(date +%s)
18101         delta=$((etime - stime))
18102         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18103
18104         stime=$(date +%s)
18105         for (( i = 0; i < $tcount; i++ )) ; do
18106                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18107         done
18108         wait
18109         etime=$(date +%s)
18110         delta=$((etime - stime))
18111         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18112
18113         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18114 }
18115 run_test 182b "Test parallel modify metadata operations from osp"
18116
18117 test_183() { # LU-2275
18118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18119         remote_mds_nodsh && skip "remote MDS with nodsh"
18120         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18121                 skip "Need MDS version at least 2.3.56"
18122
18123         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18124         echo aaa > $DIR/$tdir/$tfile
18125
18126 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18127         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18128
18129         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18130         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18131
18132         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18133
18134         # Flush negative dentry cache
18135         touch $DIR/$tdir/$tfile
18136
18137         # We are not checking for any leaked references here, they'll
18138         # become evident next time we do cleanup with module unload.
18139         rm -rf $DIR/$tdir
18140 }
18141 run_test 183 "No crash or request leak in case of strange dispositions ========"
18142
18143 # test suite 184 is for LU-2016, LU-2017
18144 test_184a() {
18145         check_swap_layouts_support
18146
18147         dir0=$DIR/$tdir/$testnum
18148         test_mkdir -p -c1 $dir0
18149         ref1=/etc/passwd
18150         ref2=/etc/group
18151         file1=$dir0/f1
18152         file2=$dir0/f2
18153         $LFS setstripe -c1 $file1
18154         cp $ref1 $file1
18155         $LFS setstripe -c2 $file2
18156         cp $ref2 $file2
18157         gen1=$($LFS getstripe -g $file1)
18158         gen2=$($LFS getstripe -g $file2)
18159
18160         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18161         gen=$($LFS getstripe -g $file1)
18162         [[ $gen1 != $gen ]] ||
18163                 error "Layout generation on $file1 does not change"
18164         gen=$($LFS getstripe -g $file2)
18165         [[ $gen2 != $gen ]] ||
18166                 error "Layout generation on $file2 does not change"
18167
18168         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18169         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18170
18171         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18172 }
18173 run_test 184a "Basic layout swap"
18174
18175 test_184b() {
18176         check_swap_layouts_support
18177
18178         dir0=$DIR/$tdir/$testnum
18179         mkdir -p $dir0 || error "creating dir $dir0"
18180         file1=$dir0/f1
18181         file2=$dir0/f2
18182         file3=$dir0/f3
18183         dir1=$dir0/d1
18184         dir2=$dir0/d2
18185         mkdir $dir1 $dir2
18186         $LFS setstripe -c1 $file1
18187         $LFS setstripe -c2 $file2
18188         $LFS setstripe -c1 $file3
18189         chown $RUNAS_ID $file3
18190         gen1=$($LFS getstripe -g $file1)
18191         gen2=$($LFS getstripe -g $file2)
18192
18193         $LFS swap_layouts $dir1 $dir2 &&
18194                 error "swap of directories layouts should fail"
18195         $LFS swap_layouts $dir1 $file1 &&
18196                 error "swap of directory and file layouts should fail"
18197         $RUNAS $LFS swap_layouts $file1 $file2 &&
18198                 error "swap of file we cannot write should fail"
18199         $LFS swap_layouts $file1 $file3 &&
18200                 error "swap of file with different owner should fail"
18201         /bin/true # to clear error code
18202 }
18203 run_test 184b "Forbidden layout swap (will generate errors)"
18204
18205 test_184c() {
18206         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18207         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18208         check_swap_layouts_support
18209         check_swap_layout_no_dom $DIR
18210
18211         local dir0=$DIR/$tdir/$testnum
18212         mkdir -p $dir0 || error "creating dir $dir0"
18213
18214         local ref1=$dir0/ref1
18215         local ref2=$dir0/ref2
18216         local file1=$dir0/file1
18217         local file2=$dir0/file2
18218         # create a file large enough for the concurrent test
18219         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18220         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18221         echo "ref file size: ref1($(stat -c %s $ref1))," \
18222              "ref2($(stat -c %s $ref2))"
18223
18224         cp $ref2 $file2
18225         dd if=$ref1 of=$file1 bs=16k &
18226         local DD_PID=$!
18227
18228         # Make sure dd starts to copy file, but wait at most 5 seconds
18229         local loops=0
18230         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18231
18232         $LFS swap_layouts $file1 $file2
18233         local rc=$?
18234         wait $DD_PID
18235         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18236         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18237
18238         # how many bytes copied before swapping layout
18239         local copied=$(stat -c %s $file2)
18240         local remaining=$(stat -c %s $ref1)
18241         remaining=$((remaining - copied))
18242         echo "Copied $copied bytes before swapping layout..."
18243
18244         cmp -n $copied $file1 $ref2 | grep differ &&
18245                 error "Content mismatch [0, $copied) of ref2 and file1"
18246         cmp -n $copied $file2 $ref1 ||
18247                 error "Content mismatch [0, $copied) of ref1 and file2"
18248         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18249                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18250
18251         # clean up
18252         rm -f $ref1 $ref2 $file1 $file2
18253 }
18254 run_test 184c "Concurrent write and layout swap"
18255
18256 test_184d() {
18257         check_swap_layouts_support
18258         check_swap_layout_no_dom $DIR
18259         [ -z "$(which getfattr 2>/dev/null)" ] &&
18260                 skip_env "no getfattr command"
18261
18262         local file1=$DIR/$tdir/$tfile-1
18263         local file2=$DIR/$tdir/$tfile-2
18264         local file3=$DIR/$tdir/$tfile-3
18265         local lovea1
18266         local lovea2
18267
18268         mkdir -p $DIR/$tdir
18269         touch $file1 || error "create $file1 failed"
18270         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18271                 error "create $file2 failed"
18272         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18273                 error "create $file3 failed"
18274         lovea1=$(get_layout_param $file1)
18275
18276         $LFS swap_layouts $file2 $file3 ||
18277                 error "swap $file2 $file3 layouts failed"
18278         $LFS swap_layouts $file1 $file2 ||
18279                 error "swap $file1 $file2 layouts failed"
18280
18281         lovea2=$(get_layout_param $file2)
18282         echo "$lovea1"
18283         echo "$lovea2"
18284         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18285
18286         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18287         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18288 }
18289 run_test 184d "allow stripeless layouts swap"
18290
18291 test_184e() {
18292         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18293                 skip "Need MDS version at least 2.6.94"
18294         check_swap_layouts_support
18295         check_swap_layout_no_dom $DIR
18296         [ -z "$(which getfattr 2>/dev/null)" ] &&
18297                 skip_env "no getfattr command"
18298
18299         local file1=$DIR/$tdir/$tfile-1
18300         local file2=$DIR/$tdir/$tfile-2
18301         local file3=$DIR/$tdir/$tfile-3
18302         local lovea
18303
18304         mkdir -p $DIR/$tdir
18305         touch $file1 || error "create $file1 failed"
18306         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18307                 error "create $file2 failed"
18308         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18309                 error "create $file3 failed"
18310
18311         $LFS swap_layouts $file1 $file2 ||
18312                 error "swap $file1 $file2 layouts failed"
18313
18314         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18315         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18316
18317         echo 123 > $file1 || error "Should be able to write into $file1"
18318
18319         $LFS swap_layouts $file1 $file3 ||
18320                 error "swap $file1 $file3 layouts failed"
18321
18322         echo 123 > $file1 || error "Should be able to write into $file1"
18323
18324         rm -rf $file1 $file2 $file3
18325 }
18326 run_test 184e "Recreate layout after stripeless layout swaps"
18327
18328 test_184f() {
18329         # Create a file with name longer than sizeof(struct stat) ==
18330         # 144 to see if we can get chars from the file name to appear
18331         # in the returned striping. Note that 'f' == 0x66.
18332         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18333
18334         mkdir -p $DIR/$tdir
18335         mcreate $DIR/$tdir/$file
18336         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18337                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18338         fi
18339 }
18340 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18341
18342 test_185() { # LU-2441
18343         # LU-3553 - no volatile file support in old servers
18344         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18345                 skip "Need MDS version at least 2.3.60"
18346
18347         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18348         touch $DIR/$tdir/spoo
18349         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18350         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18351                 error "cannot create/write a volatile file"
18352         [ "$FILESET" == "" ] &&
18353         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18354                 error "FID is still valid after close"
18355
18356         multiop_bg_pause $DIR/$tdir vVw4096_c
18357         local multi_pid=$!
18358
18359         local OLD_IFS=$IFS
18360         IFS=":"
18361         local fidv=($fid)
18362         IFS=$OLD_IFS
18363         # assume that the next FID for this client is sequential, since stdout
18364         # is unfortunately eaten by multiop_bg_pause
18365         local n=$((${fidv[1]} + 1))
18366         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18367         if [ "$FILESET" == "" ]; then
18368                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18369                         error "FID is missing before close"
18370         fi
18371         kill -USR1 $multi_pid
18372         # 1 second delay, so if mtime change we will see it
18373         sleep 1
18374         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18375         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18376 }
18377 run_test 185 "Volatile file support"
18378
18379 function create_check_volatile() {
18380         local idx=$1
18381         local tgt
18382
18383         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18384         local PID=$!
18385         sleep 1
18386         local FID=$(cat /tmp/${tfile}.fid)
18387         [ "$FID" == "" ] && error "can't get FID for volatile"
18388         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18389         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18390         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18391         kill -USR1 $PID
18392         wait
18393         sleep 1
18394         cancel_lru_locks mdc # flush opencache
18395         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18396         return 0
18397 }
18398
18399 test_185a(){
18400         # LU-12516 - volatile creation via .lustre
18401         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18402                 skip "Need MDS version at least 2.3.55"
18403
18404         create_check_volatile 0
18405         [ $MDSCOUNT -lt 2 ] && return 0
18406
18407         # DNE case
18408         create_check_volatile 1
18409
18410         return 0
18411 }
18412 run_test 185a "Volatile file creation in .lustre/fid/"
18413
18414 test_187a() {
18415         remote_mds_nodsh && skip "remote MDS with nodsh"
18416         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18417                 skip "Need MDS version at least 2.3.0"
18418
18419         local dir0=$DIR/$tdir/$testnum
18420         mkdir -p $dir0 || error "creating dir $dir0"
18421
18422         local file=$dir0/file1
18423         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18424         local dv1=$($LFS data_version $file)
18425         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18426         local dv2=$($LFS data_version $file)
18427         [[ $dv1 != $dv2 ]] ||
18428                 error "data version did not change on write $dv1 == $dv2"
18429
18430         # clean up
18431         rm -f $file1
18432 }
18433 run_test 187a "Test data version change"
18434
18435 test_187b() {
18436         remote_mds_nodsh && skip "remote MDS with nodsh"
18437         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18438                 skip "Need MDS version at least 2.3.0"
18439
18440         local dir0=$DIR/$tdir/$testnum
18441         mkdir -p $dir0 || error "creating dir $dir0"
18442
18443         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18444         [[ ${DV[0]} != ${DV[1]} ]] ||
18445                 error "data version did not change on write"\
18446                       " ${DV[0]} == ${DV[1]}"
18447
18448         # clean up
18449         rm -f $file1
18450 }
18451 run_test 187b "Test data version change on volatile file"
18452
18453 test_200() {
18454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18455         remote_mgs_nodsh && skip "remote MGS with nodsh"
18456         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18457
18458         local POOL=${POOL:-cea1}
18459         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18460         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18461         # Pool OST targets
18462         local first_ost=0
18463         local last_ost=$(($OSTCOUNT - 1))
18464         local ost_step=2
18465         local ost_list=$(seq $first_ost $ost_step $last_ost)
18466         local ost_range="$first_ost $last_ost $ost_step"
18467         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18468         local file_dir=$POOL_ROOT/file_tst
18469         local subdir=$test_path/subdir
18470         local rc=0
18471
18472         while : ; do
18473                 # former test_200a test_200b
18474                 pool_add $POOL                          || { rc=$? ; break; }
18475                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18476                 # former test_200c test_200d
18477                 mkdir -p $test_path
18478                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18479                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18480                 mkdir -p $subdir
18481                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18482                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18483                                                         || { rc=$? ; break; }
18484                 # former test_200e test_200f
18485                 local files=$((OSTCOUNT*3))
18486                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18487                                                         || { rc=$? ; break; }
18488                 pool_create_files $POOL $file_dir $files "$ost_list" \
18489                                                         || { rc=$? ; break; }
18490                 # former test_200g test_200h
18491                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18492                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18493
18494                 # former test_201a test_201b test_201c
18495                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18496
18497                 local f=$test_path/$tfile
18498                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18499                 pool_remove $POOL $f                    || { rc=$? ; break; }
18500                 break
18501         done
18502
18503         destroy_test_pools
18504
18505         return $rc
18506 }
18507 run_test 200 "OST pools"
18508
18509 # usage: default_attr <count | size | offset>
18510 default_attr() {
18511         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18512 }
18513
18514 # usage: check_default_stripe_attr
18515 check_default_stripe_attr() {
18516         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18517         case $1 in
18518         --stripe-count|-c)
18519                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18520         --stripe-size|-S)
18521                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18522         --stripe-index|-i)
18523                 EXPECTED=-1;;
18524         *)
18525                 error "unknown getstripe attr '$1'"
18526         esac
18527
18528         [ $ACTUAL == $EXPECTED ] ||
18529                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18530 }
18531
18532 test_204a() {
18533         test_mkdir $DIR/$tdir
18534         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18535
18536         check_default_stripe_attr --stripe-count
18537         check_default_stripe_attr --stripe-size
18538         check_default_stripe_attr --stripe-index
18539 }
18540 run_test 204a "Print default stripe attributes"
18541
18542 test_204b() {
18543         test_mkdir $DIR/$tdir
18544         $LFS setstripe --stripe-count 1 $DIR/$tdir
18545
18546         check_default_stripe_attr --stripe-size
18547         check_default_stripe_attr --stripe-index
18548 }
18549 run_test 204b "Print default stripe size and offset"
18550
18551 test_204c() {
18552         test_mkdir $DIR/$tdir
18553         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18554
18555         check_default_stripe_attr --stripe-count
18556         check_default_stripe_attr --stripe-index
18557 }
18558 run_test 204c "Print default stripe count and offset"
18559
18560 test_204d() {
18561         test_mkdir $DIR/$tdir
18562         $LFS setstripe --stripe-index 0 $DIR/$tdir
18563
18564         check_default_stripe_attr --stripe-count
18565         check_default_stripe_attr --stripe-size
18566 }
18567 run_test 204d "Print default stripe count and size"
18568
18569 test_204e() {
18570         test_mkdir $DIR/$tdir
18571         $LFS setstripe -d $DIR/$tdir
18572
18573         check_default_stripe_attr --stripe-count --raw
18574         check_default_stripe_attr --stripe-size --raw
18575         check_default_stripe_attr --stripe-index --raw
18576 }
18577 run_test 204e "Print raw stripe attributes"
18578
18579 test_204f() {
18580         test_mkdir $DIR/$tdir
18581         $LFS setstripe --stripe-count 1 $DIR/$tdir
18582
18583         check_default_stripe_attr --stripe-size --raw
18584         check_default_stripe_attr --stripe-index --raw
18585 }
18586 run_test 204f "Print raw stripe size and offset"
18587
18588 test_204g() {
18589         test_mkdir $DIR/$tdir
18590         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18591
18592         check_default_stripe_attr --stripe-count --raw
18593         check_default_stripe_attr --stripe-index --raw
18594 }
18595 run_test 204g "Print raw stripe count and offset"
18596
18597 test_204h() {
18598         test_mkdir $DIR/$tdir
18599         $LFS setstripe --stripe-index 0 $DIR/$tdir
18600
18601         check_default_stripe_attr --stripe-count --raw
18602         check_default_stripe_attr --stripe-size --raw
18603 }
18604 run_test 204h "Print raw stripe count and size"
18605
18606 # Figure out which job scheduler is being used, if any,
18607 # or use a fake one
18608 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18609         JOBENV=SLURM_JOB_ID
18610 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18611         JOBENV=LSB_JOBID
18612 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18613         JOBENV=PBS_JOBID
18614 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18615         JOBENV=LOADL_STEP_ID
18616 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18617         JOBENV=JOB_ID
18618 else
18619         $LCTL list_param jobid_name > /dev/null 2>&1
18620         if [ $? -eq 0 ]; then
18621                 JOBENV=nodelocal
18622         else
18623                 JOBENV=FAKE_JOBID
18624         fi
18625 fi
18626 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18627
18628 verify_jobstats() {
18629         local cmd=($1)
18630         shift
18631         local facets="$@"
18632
18633 # we don't really need to clear the stats for this test to work, since each
18634 # command has a unique jobid, but it makes debugging easier if needed.
18635 #       for facet in $facets; do
18636 #               local dev=$(convert_facet2label $facet)
18637 #               # clear old jobstats
18638 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18639 #       done
18640
18641         # use a new JobID for each test, or we might see an old one
18642         [ "$JOBENV" = "FAKE_JOBID" ] &&
18643                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18644
18645         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18646
18647         [ "$JOBENV" = "nodelocal" ] && {
18648                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18649                 $LCTL set_param jobid_name=$FAKE_JOBID
18650                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18651         }
18652
18653         log "Test: ${cmd[*]}"
18654         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18655
18656         if [ $JOBENV = "FAKE_JOBID" ]; then
18657                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18658         else
18659                 ${cmd[*]}
18660         fi
18661
18662         # all files are created on OST0000
18663         for facet in $facets; do
18664                 local stats="*.$(convert_facet2label $facet).job_stats"
18665
18666                 # strip out libtool wrappers for in-tree executables
18667                 if (( $(do_facet $facet lctl get_param $stats |
18668                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18669                         do_facet $facet lctl get_param $stats
18670                         error "No jobstats for $JOBVAL found on $facet::$stats"
18671                 fi
18672         done
18673 }
18674
18675 jobstats_set() {
18676         local new_jobenv=$1
18677
18678         set_persistent_param_and_check client "jobid_var" \
18679                 "$FSNAME.sys.jobid_var" $new_jobenv
18680 }
18681
18682 test_205a() { # Job stats
18683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18684         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18685                 skip "Need MDS version with at least 2.7.1"
18686         remote_mgs_nodsh && skip "remote MGS with nodsh"
18687         remote_mds_nodsh && skip "remote MDS with nodsh"
18688         remote_ost_nodsh && skip "remote OST with nodsh"
18689         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18690                 skip "Server doesn't support jobstats"
18691         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18692
18693         local old_jobenv=$($LCTL get_param -n jobid_var)
18694         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18695
18696         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18697                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18698         else
18699                 stack_trap "do_facet mgs $PERM_CMD \
18700                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18701         fi
18702         changelog_register
18703
18704         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18705                                 mdt.*.job_cleanup_interval | head -n 1)
18706         local new_interval=5
18707         do_facet $SINGLEMDS \
18708                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18709         stack_trap "do_facet $SINGLEMDS \
18710                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18711         local start=$SECONDS
18712
18713         local cmd
18714         # mkdir
18715         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18716         verify_jobstats "$cmd" "$SINGLEMDS"
18717         # rmdir
18718         cmd="rmdir $DIR/$tdir"
18719         verify_jobstats "$cmd" "$SINGLEMDS"
18720         # mkdir on secondary MDT
18721         if [ $MDSCOUNT -gt 1 ]; then
18722                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18723                 verify_jobstats "$cmd" "mds2"
18724         fi
18725         # mknod
18726         cmd="mknod $DIR/$tfile c 1 3"
18727         verify_jobstats "$cmd" "$SINGLEMDS"
18728         # unlink
18729         cmd="rm -f $DIR/$tfile"
18730         verify_jobstats "$cmd" "$SINGLEMDS"
18731         # create all files on OST0000 so verify_jobstats can find OST stats
18732         # open & close
18733         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18734         verify_jobstats "$cmd" "$SINGLEMDS"
18735         # setattr
18736         cmd="touch $DIR/$tfile"
18737         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18738         # write
18739         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18740         verify_jobstats "$cmd" "ost1"
18741         # read
18742         cancel_lru_locks osc
18743         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18744         verify_jobstats "$cmd" "ost1"
18745         # truncate
18746         cmd="$TRUNCATE $DIR/$tfile 0"
18747         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18748         # rename
18749         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18750         verify_jobstats "$cmd" "$SINGLEMDS"
18751         # jobstats expiry - sleep until old stats should be expired
18752         local left=$((new_interval + 5 - (SECONDS - start)))
18753         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18754                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18755                         "0" $left
18756         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18757         verify_jobstats "$cmd" "$SINGLEMDS"
18758         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18759             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18760
18761         # Ensure that jobid are present in changelog (if supported by MDS)
18762         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18763                 changelog_dump | tail -10
18764                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18765                 [ $jobids -eq 9 ] ||
18766                         error "Wrong changelog jobid count $jobids != 9"
18767
18768                 # LU-5862
18769                 JOBENV="disable"
18770                 jobstats_set $JOBENV
18771                 touch $DIR/$tfile
18772                 changelog_dump | grep $tfile
18773                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18774                 [ $jobids -eq 0 ] ||
18775                         error "Unexpected jobids when jobid_var=$JOBENV"
18776         fi
18777
18778         # test '%j' access to environment variable - if supported
18779         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18780                 JOBENV="JOBCOMPLEX"
18781                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18782
18783                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18784         fi
18785
18786         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18787                 JOBENV="JOBCOMPLEX"
18788                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18789
18790                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18791         fi
18792
18793         # test '%j' access to per-session jobid - if supported
18794         if lctl list_param jobid_this_session > /dev/null 2>&1
18795         then
18796                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18797                 lctl set_param jobid_this_session=$USER
18798
18799                 JOBENV="JOBCOMPLEX"
18800                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18801
18802                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18803         fi
18804 }
18805 run_test 205a "Verify job stats"
18806
18807 # LU-13117, LU-13597
18808 test_205b() {
18809         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18810                 skip "Need MDS version at least 2.13.54.91"
18811
18812         local job_stats="mdt.*.job_stats"
18813         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18814
18815         do_facet mds1 $LCTL set_param $job_stats=clear
18816
18817         # Setting jobid_var to USER might not be supported
18818         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18819         $LCTL set_param jobid_var=USER || true
18820         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18821         $LCTL set_param jobid_name="%j.%e.%u"
18822
18823         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18824         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18825                 { do_facet mds1 $LCTL get_param $job_stats;
18826                   error "Unexpected jobid found"; }
18827         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18828                 { do_facet mds1 $LCTL get_param $job_stats;
18829                   error "wrong job_stats format found"; }
18830
18831         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18832                 echo "MDS does not yet escape jobid" && return 0
18833         $LCTL set_param jobid_var=TEST205b
18834         env -i TEST205b="has sp" touch $DIR/$tfile.2
18835         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18836                 { do_facet mds1 $LCTL get_param $job_stats;
18837                   error "jobid not escaped"; }
18838 }
18839 run_test 205b "Verify job stats jobid and output format"
18840
18841 # LU-13733
18842 test_205c() {
18843         $LCTL set_param llite.*.stats=0
18844         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18845         $LCTL get_param llite.*.stats
18846         $LCTL get_param llite.*.stats | grep \
18847                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18848                         error "wrong client stats format found"
18849 }
18850 run_test 205c "Verify client stats format"
18851
18852 # LU-1480, LU-1773 and LU-1657
18853 test_206() {
18854         mkdir -p $DIR/$tdir
18855         $LFS setstripe -c -1 $DIR/$tdir
18856 #define OBD_FAIL_LOV_INIT 0x1403
18857         $LCTL set_param fail_loc=0xa0001403
18858         $LCTL set_param fail_val=1
18859         touch $DIR/$tdir/$tfile || true
18860 }
18861 run_test 206 "fail lov_init_raid0() doesn't lbug"
18862
18863 test_207a() {
18864         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18865         local fsz=`stat -c %s $DIR/$tfile`
18866         cancel_lru_locks mdc
18867
18868         # do not return layout in getattr intent
18869 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18870         $LCTL set_param fail_loc=0x170
18871         local sz=`stat -c %s $DIR/$tfile`
18872
18873         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18874
18875         rm -rf $DIR/$tfile
18876 }
18877 run_test 207a "can refresh layout at glimpse"
18878
18879 test_207b() {
18880         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18881         local cksum=`md5sum $DIR/$tfile`
18882         local fsz=`stat -c %s $DIR/$tfile`
18883         cancel_lru_locks mdc
18884         cancel_lru_locks osc
18885
18886         # do not return layout in getattr intent
18887 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18888         $LCTL set_param fail_loc=0x171
18889
18890         # it will refresh layout after the file is opened but before read issues
18891         echo checksum is "$cksum"
18892         echo "$cksum" |md5sum -c --quiet || error "file differs"
18893
18894         rm -rf $DIR/$tfile
18895 }
18896 run_test 207b "can refresh layout at open"
18897
18898 test_208() {
18899         # FIXME: in this test suite, only RD lease is used. This is okay
18900         # for now as only exclusive open is supported. After generic lease
18901         # is done, this test suite should be revised. - Jinshan
18902
18903         remote_mds_nodsh && skip "remote MDS with nodsh"
18904         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18905                 skip "Need MDS version at least 2.4.52"
18906
18907         echo "==== test 1: verify get lease work"
18908         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18909
18910         echo "==== test 2: verify lease can be broken by upcoming open"
18911         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18912         local PID=$!
18913         sleep 2
18914
18915         $MULTIOP $DIR/$tfile oO_RDWR:c
18916         kill -USR1 $PID && wait $PID || error "break lease error"
18917
18918         echo "==== test 3: verify lease can't be granted if an open already exists"
18919         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18920         local PID=$!
18921         sleep 2
18922
18923         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18924         kill -USR1 $PID && wait $PID || error "open file error"
18925
18926         echo "==== test 4: lease can sustain over recovery"
18927         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18928         PID=$!
18929         sleep 2
18930
18931         fail mds1
18932
18933         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18934
18935         echo "==== test 5: lease broken can't be regained by replay"
18936         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18937         PID=$!
18938         sleep 2
18939
18940         # open file to break lease and then recovery
18941         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18942         fail mds1
18943
18944         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18945
18946         rm -f $DIR/$tfile
18947 }
18948 run_test 208 "Exclusive open"
18949
18950 test_209() {
18951         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18952                 skip_env "must have disp_stripe"
18953
18954         touch $DIR/$tfile
18955         sync; sleep 5; sync;
18956
18957         echo 3 > /proc/sys/vm/drop_caches
18958         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18959                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18960         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18961
18962         # open/close 500 times
18963         for i in $(seq 500); do
18964                 cat $DIR/$tfile
18965         done
18966
18967         echo 3 > /proc/sys/vm/drop_caches
18968         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18969                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18970         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18971
18972         echo "before: $req_before, after: $req_after"
18973         [ $((req_after - req_before)) -ge 300 ] &&
18974                 error "open/close requests are not freed"
18975         return 0
18976 }
18977 run_test 209 "read-only open/close requests should be freed promptly"
18978
18979 test_210() {
18980         local pid
18981
18982         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18983         pid=$!
18984         sleep 1
18985
18986         $LFS getstripe $DIR/$tfile
18987         kill -USR1 $pid
18988         wait $pid || error "multiop failed"
18989
18990         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18991         pid=$!
18992         sleep 1
18993
18994         $LFS getstripe $DIR/$tfile
18995         kill -USR1 $pid
18996         wait $pid || error "multiop failed"
18997 }
18998 run_test 210 "lfs getstripe does not break leases"
18999
19000 test_212() {
19001         size=`date +%s`
19002         size=$((size % 8192 + 1))
19003         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19004         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19005         rm -f $DIR/f212 $DIR/f212.xyz
19006 }
19007 run_test 212 "Sendfile test ============================================"
19008
19009 test_213() {
19010         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19011         cancel_lru_locks osc
19012         lctl set_param fail_loc=0x8000040f
19013         # generate a read lock
19014         cat $DIR/$tfile > /dev/null
19015         # write to the file, it will try to cancel the above read lock.
19016         cat /etc/hosts >> $DIR/$tfile
19017 }
19018 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19019
19020 test_214() { # for bug 20133
19021         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19022         for (( i=0; i < 340; i++ )) ; do
19023                 touch $DIR/$tdir/d214c/a$i
19024         done
19025
19026         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19027         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19028         ls $DIR/d214c || error "ls $DIR/d214c failed"
19029         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19030         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19031 }
19032 run_test 214 "hash-indexed directory test - bug 20133"
19033
19034 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19035 create_lnet_proc_files() {
19036         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19037 }
19038
19039 # counterpart of create_lnet_proc_files
19040 remove_lnet_proc_files() {
19041         rm -f $TMP/lnet_$1.sys
19042 }
19043
19044 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19045 # 3rd arg as regexp for body
19046 check_lnet_proc_stats() {
19047         local l=$(cat "$TMP/lnet_$1" |wc -l)
19048         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19049
19050         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19051 }
19052
19053 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19054 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19055 # optional and can be regexp for 2nd line (lnet.routes case)
19056 check_lnet_proc_entry() {
19057         local blp=2          # blp stands for 'position of 1st line of body'
19058         [ -z "$5" ] || blp=3 # lnet.routes case
19059
19060         local l=$(cat "$TMP/lnet_$1" |wc -l)
19061         # subtracting one from $blp because the body can be empty
19062         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19063
19064         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19065                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19066
19067         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19068                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19069
19070         # bail out if any unexpected line happened
19071         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19072         [ "$?" != 0 ] || error "$2 misformatted"
19073 }
19074
19075 test_215() { # for bugs 18102, 21079, 21517
19076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19077
19078         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19079         local P='[1-9][0-9]*'           # positive numeric
19080         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19081         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19082         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19083         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19084
19085         local L1 # regexp for 1st line
19086         local L2 # regexp for 2nd line (optional)
19087         local BR # regexp for the rest (body)
19088
19089         # lnet.stats should look as 11 space-separated non-negative numerics
19090         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19091         create_lnet_proc_files "stats"
19092         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19093         remove_lnet_proc_files "stats"
19094
19095         # lnet.routes should look like this:
19096         # Routing disabled/enabled
19097         # net hops priority state router
19098         # where net is a string like tcp0, hops > 0, priority >= 0,
19099         # state is up/down,
19100         # router is a string like 192.168.1.1@tcp2
19101         L1="^Routing (disabled|enabled)$"
19102         L2="^net +hops +priority +state +router$"
19103         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19104         create_lnet_proc_files "routes"
19105         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19106         remove_lnet_proc_files "routes"
19107
19108         # lnet.routers should look like this:
19109         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19110         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19111         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19112         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19113         L1="^ref +rtr_ref +alive +router$"
19114         BR="^$P +$P +(up|down) +$NID$"
19115         create_lnet_proc_files "routers"
19116         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19117         remove_lnet_proc_files "routers"
19118
19119         # lnet.peers should look like this:
19120         # nid refs state last max rtr min tx min queue
19121         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19122         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19123         # numeric (0 or >0 or <0), queue >= 0.
19124         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19125         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19126         create_lnet_proc_files "peers"
19127         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19128         remove_lnet_proc_files "peers"
19129
19130         # lnet.buffers  should look like this:
19131         # pages count credits min
19132         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19133         L1="^pages +count +credits +min$"
19134         BR="^ +$N +$N +$I +$I$"
19135         create_lnet_proc_files "buffers"
19136         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19137         remove_lnet_proc_files "buffers"
19138
19139         # lnet.nis should look like this:
19140         # nid status alive refs peer rtr max tx min
19141         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19142         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19143         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19144         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19145         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19146         create_lnet_proc_files "nis"
19147         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19148         remove_lnet_proc_files "nis"
19149
19150         # can we successfully write to lnet.stats?
19151         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19152 }
19153 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19154
19155 test_216() { # bug 20317
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         remote_ost_nodsh && skip "remote OST with nodsh"
19158
19159         local node
19160         local facets=$(get_facets OST)
19161         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19162
19163         save_lustre_params client "osc.*.contention_seconds" > $p
19164         save_lustre_params $facets \
19165                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19166         save_lustre_params $facets \
19167                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19168         save_lustre_params $facets \
19169                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19170         clear_stats osc.*.osc_stats
19171
19172         # agressive lockless i/o settings
19173         do_nodes $(comma_list $(osts_nodes)) \
19174                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19175                         ldlm.namespaces.filter-*.contended_locks=0 \
19176                         ldlm.namespaces.filter-*.contention_seconds=60"
19177         lctl set_param -n osc.*.contention_seconds=60
19178
19179         $DIRECTIO write $DIR/$tfile 0 10 4096
19180         $CHECKSTAT -s 40960 $DIR/$tfile
19181
19182         # disable lockless i/o
19183         do_nodes $(comma_list $(osts_nodes)) \
19184                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19185                         ldlm.namespaces.filter-*.contended_locks=32 \
19186                         ldlm.namespaces.filter-*.contention_seconds=0"
19187         lctl set_param -n osc.*.contention_seconds=0
19188         clear_stats osc.*.osc_stats
19189
19190         dd if=/dev/zero of=$DIR/$tfile count=0
19191         $CHECKSTAT -s 0 $DIR/$tfile
19192
19193         restore_lustre_params <$p
19194         rm -f $p
19195         rm $DIR/$tfile
19196 }
19197 run_test 216 "check lockless direct write updates file size and kms correctly"
19198
19199 test_217() { # bug 22430
19200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19201
19202         local node
19203         local nid
19204
19205         for node in $(nodes_list); do
19206                 nid=$(host_nids_address $node $NETTYPE)
19207                 if [[ $nid = *-* ]] ; then
19208                         echo "lctl ping $(h2nettype $nid)"
19209                         lctl ping $(h2nettype $nid)
19210                 else
19211                         echo "skipping $node (no hyphen detected)"
19212                 fi
19213         done
19214 }
19215 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19216
19217 test_218() {
19218        # do directio so as not to populate the page cache
19219        log "creating a 10 Mb file"
19220        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19221        log "starting reads"
19222        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19223        log "truncating the file"
19224        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19225        log "killing dd"
19226        kill %+ || true # reads might have finished
19227        echo "wait until dd is finished"
19228        wait
19229        log "removing the temporary file"
19230        rm -rf $DIR/$tfile || error "tmp file removal failed"
19231 }
19232 run_test 218 "parallel read and truncate should not deadlock"
19233
19234 test_219() {
19235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19236
19237         # write one partial page
19238         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19239         # set no grant so vvp_io_commit_write will do sync write
19240         $LCTL set_param fail_loc=0x411
19241         # write a full page at the end of file
19242         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19243
19244         $LCTL set_param fail_loc=0
19245         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19246         $LCTL set_param fail_loc=0x411
19247         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19248
19249         # LU-4201
19250         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19251         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19252 }
19253 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19254
19255 test_220() { #LU-325
19256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19257         remote_ost_nodsh && skip "remote OST with nodsh"
19258         remote_mds_nodsh && skip "remote MDS with nodsh"
19259         remote_mgs_nodsh && skip "remote MGS with nodsh"
19260
19261         local OSTIDX=0
19262
19263         # create on MDT0000 so the last_id and next_id are correct
19264         mkdir_on_mdt0 $DIR/$tdir
19265         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19266         OST=${OST%_UUID}
19267
19268         # on the mdt's osc
19269         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19270         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19271                         osp.$mdtosc_proc1.prealloc_last_id)
19272         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19273                         osp.$mdtosc_proc1.prealloc_next_id)
19274
19275         $LFS df -i
19276
19277         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19278         #define OBD_FAIL_OST_ENOINO              0x229
19279         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19280         create_pool $FSNAME.$TESTNAME || return 1
19281         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19282
19283         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19284
19285         MDSOBJS=$((last_id - next_id))
19286         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19287
19288         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19289         echo "OST still has $count kbytes free"
19290
19291         echo "create $MDSOBJS files @next_id..."
19292         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19293
19294         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19295                         osp.$mdtosc_proc1.prealloc_last_id)
19296         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19297                         osp.$mdtosc_proc1.prealloc_next_id)
19298
19299         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19300         $LFS df -i
19301
19302         echo "cleanup..."
19303
19304         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19305         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19306
19307         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19308                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19309         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19310                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19311         echo "unlink $MDSOBJS files @$next_id..."
19312         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19313 }
19314 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19315
19316 test_221() {
19317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19318
19319         dd if=`which date` of=$MOUNT/date oflag=sync
19320         chmod +x $MOUNT/date
19321
19322         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19323         $LCTL set_param fail_loc=0x80001401
19324
19325         $MOUNT/date > /dev/null
19326         rm -f $MOUNT/date
19327 }
19328 run_test 221 "make sure fault and truncate race to not cause OOM"
19329
19330 test_222a () {
19331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19332
19333         rm -rf $DIR/$tdir
19334         test_mkdir $DIR/$tdir
19335         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19336         createmany -o $DIR/$tdir/$tfile 10
19337         cancel_lru_locks mdc
19338         cancel_lru_locks osc
19339         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19340         $LCTL set_param fail_loc=0x31a
19341         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19342         $LCTL set_param fail_loc=0
19343         rm -r $DIR/$tdir
19344 }
19345 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19346
19347 test_222b () {
19348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19349
19350         rm -rf $DIR/$tdir
19351         test_mkdir $DIR/$tdir
19352         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19353         createmany -o $DIR/$tdir/$tfile 10
19354         cancel_lru_locks mdc
19355         cancel_lru_locks osc
19356         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19357         $LCTL set_param fail_loc=0x31a
19358         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19359         $LCTL set_param fail_loc=0
19360 }
19361 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19362
19363 test_223 () {
19364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19365
19366         rm -rf $DIR/$tdir
19367         test_mkdir $DIR/$tdir
19368         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19369         createmany -o $DIR/$tdir/$tfile 10
19370         cancel_lru_locks mdc
19371         cancel_lru_locks osc
19372         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19373         $LCTL set_param fail_loc=0x31b
19374         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19375         $LCTL set_param fail_loc=0
19376         rm -r $DIR/$tdir
19377 }
19378 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19379
19380 test_224a() { # LU-1039, MRP-303
19381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19382         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19383         $LCTL set_param fail_loc=0x508
19384         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19385         $LCTL set_param fail_loc=0
19386         df $DIR
19387 }
19388 run_test 224a "Don't panic on bulk IO failure"
19389
19390 test_224bd_sub() { # LU-1039, MRP-303
19391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19392         local timeout=$1
19393
19394         shift
19395         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19396
19397         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19398
19399         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19400         cancel_lru_locks osc
19401         set_checksums 0
19402         stack_trap "set_checksums $ORIG_CSUM" EXIT
19403         local at_max_saved=0
19404
19405         # adaptive timeouts may prevent seeing the issue
19406         if at_is_enabled; then
19407                 at_max_saved=$(at_max_get mds)
19408                 at_max_set 0 mds client
19409                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19410         fi
19411
19412         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19413         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19414         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19415
19416         do_facet ost1 $LCTL set_param fail_loc=0
19417         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19418         df $DIR
19419 }
19420
19421 test_224b() {
19422         test_224bd_sub 3 error "dd failed"
19423 }
19424 run_test 224b "Don't panic on bulk IO failure"
19425
19426 test_224c() { # LU-6441
19427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19428         remote_mds_nodsh && skip "remote MDS with nodsh"
19429
19430         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19431         save_writethrough $p
19432         set_cache writethrough on
19433
19434         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19435         local at_max=$($LCTL get_param -n at_max)
19436         local timeout=$($LCTL get_param -n timeout)
19437         local test_at="at_max"
19438         local param_at="$FSNAME.sys.at_max"
19439         local test_timeout="timeout"
19440         local param_timeout="$FSNAME.sys.timeout"
19441
19442         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19443
19444         set_persistent_param_and_check client "$test_at" "$param_at" 0
19445         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19446
19447         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19448         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19449         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19450         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19451         sync
19452         do_facet ost1 "$LCTL set_param fail_loc=0"
19453
19454         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19455         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19456                 $timeout
19457
19458         $LCTL set_param -n $pages_per_rpc
19459         restore_lustre_params < $p
19460         rm -f $p
19461 }
19462 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19463
19464 test_224d() { # LU-11169
19465         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19466 }
19467 run_test 224d "Don't corrupt data on bulk IO timeout"
19468
19469 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19470 test_225a () {
19471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19472         if [ -z ${MDSSURVEY} ]; then
19473                 skip_env "mds-survey not found"
19474         fi
19475         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19476                 skip "Need MDS version at least 2.2.51"
19477
19478         local mds=$(facet_host $SINGLEMDS)
19479         local target=$(do_nodes $mds 'lctl dl' |
19480                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19481
19482         local cmd1="file_count=1000 thrhi=4"
19483         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19484         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19485         local cmd="$cmd1 $cmd2 $cmd3"
19486
19487         rm -f ${TMP}/mds_survey*
19488         echo + $cmd
19489         eval $cmd || error "mds-survey with zero-stripe failed"
19490         cat ${TMP}/mds_survey*
19491         rm -f ${TMP}/mds_survey*
19492 }
19493 run_test 225a "Metadata survey sanity with zero-stripe"
19494
19495 test_225b () {
19496         if [ -z ${MDSSURVEY} ]; then
19497                 skip_env "mds-survey not found"
19498         fi
19499         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19500                 skip "Need MDS version at least 2.2.51"
19501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19502         remote_mds_nodsh && skip "remote MDS with nodsh"
19503         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19504                 skip_env "Need to mount OST to test"
19505         fi
19506
19507         local mds=$(facet_host $SINGLEMDS)
19508         local target=$(do_nodes $mds 'lctl dl' |
19509                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19510
19511         local cmd1="file_count=1000 thrhi=4"
19512         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19513         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19514         local cmd="$cmd1 $cmd2 $cmd3"
19515
19516         rm -f ${TMP}/mds_survey*
19517         echo + $cmd
19518         eval $cmd || error "mds-survey with stripe_count failed"
19519         cat ${TMP}/mds_survey*
19520         rm -f ${TMP}/mds_survey*
19521 }
19522 run_test 225b "Metadata survey sanity with stripe_count = 1"
19523
19524 mcreate_path2fid () {
19525         local mode=$1
19526         local major=$2
19527         local minor=$3
19528         local name=$4
19529         local desc=$5
19530         local path=$DIR/$tdir/$name
19531         local fid
19532         local rc
19533         local fid_path
19534
19535         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19536                 error "cannot create $desc"
19537
19538         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19539         rc=$?
19540         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19541
19542         fid_path=$($LFS fid2path $MOUNT $fid)
19543         rc=$?
19544         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19545
19546         [ "$path" == "$fid_path" ] ||
19547                 error "fid2path returned $fid_path, expected $path"
19548
19549         echo "pass with $path and $fid"
19550 }
19551
19552 test_226a () {
19553         rm -rf $DIR/$tdir
19554         mkdir -p $DIR/$tdir
19555
19556         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19557         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19558         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19559         mcreate_path2fid 0040666 0 0 dir "directory"
19560         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19561         mcreate_path2fid 0100666 0 0 file "regular file"
19562         mcreate_path2fid 0120666 0 0 link "symbolic link"
19563         mcreate_path2fid 0140666 0 0 sock "socket"
19564 }
19565 run_test 226a "call path2fid and fid2path on files of all type"
19566
19567 test_226b () {
19568         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19569
19570         local MDTIDX=1
19571
19572         rm -rf $DIR/$tdir
19573         mkdir -p $DIR/$tdir
19574         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19575                 error "create remote directory failed"
19576         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19577         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19578                                 "character special file (null)"
19579         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19580                                 "character special file (no device)"
19581         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19582         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19583                                 "block special file (loop)"
19584         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19585         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19586         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19587 }
19588 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19589
19590 test_226c () {
19591         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19592         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19593                 skip "Need MDS version at least 2.13.55"
19594
19595         local submnt=/mnt/submnt
19596         local srcfile=/etc/passwd
19597         local dstfile=$submnt/passwd
19598         local path
19599         local fid
19600
19601         rm -rf $DIR/$tdir
19602         rm -rf $submnt
19603         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19604                 error "create remote directory failed"
19605         mkdir -p $submnt || error "create $submnt failed"
19606         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19607                 error "mount $submnt failed"
19608         stack_trap "umount $submnt" EXIT
19609
19610         cp $srcfile $dstfile
19611         fid=$($LFS path2fid $dstfile)
19612         path=$($LFS fid2path $submnt "$fid")
19613         [ "$path" = "$dstfile" ] ||
19614                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19615 }
19616 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19617
19618 # LU-1299 Executing or running ldd on a truncated executable does not
19619 # cause an out-of-memory condition.
19620 test_227() {
19621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19622         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19623
19624         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19625         chmod +x $MOUNT/date
19626
19627         $MOUNT/date > /dev/null
19628         ldd $MOUNT/date > /dev/null
19629         rm -f $MOUNT/date
19630 }
19631 run_test 227 "running truncated executable does not cause OOM"
19632
19633 # LU-1512 try to reuse idle OI blocks
19634 test_228a() {
19635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19636         remote_mds_nodsh && skip "remote MDS with nodsh"
19637         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19638
19639         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19640         local myDIR=$DIR/$tdir
19641
19642         mkdir -p $myDIR
19643         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19644         $LCTL set_param fail_loc=0x80001002
19645         createmany -o $myDIR/t- 10000
19646         $LCTL set_param fail_loc=0
19647         # The guard is current the largest FID holder
19648         touch $myDIR/guard
19649         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19650                     tr -d '[')
19651         local IDX=$(($SEQ % 64))
19652
19653         do_facet $SINGLEMDS sync
19654         # Make sure journal flushed.
19655         sleep 6
19656         local blk1=$(do_facet $SINGLEMDS \
19657                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19658                      grep Blockcount | awk '{print $4}')
19659
19660         # Remove old files, some OI blocks will become idle.
19661         unlinkmany $myDIR/t- 10000
19662         # Create new files, idle OI blocks should be reused.
19663         createmany -o $myDIR/t- 2000
19664         do_facet $SINGLEMDS sync
19665         # Make sure journal flushed.
19666         sleep 6
19667         local blk2=$(do_facet $SINGLEMDS \
19668                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19669                      grep Blockcount | awk '{print $4}')
19670
19671         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19672 }
19673 run_test 228a "try to reuse idle OI blocks"
19674
19675 test_228b() {
19676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19677         remote_mds_nodsh && skip "remote MDS with nodsh"
19678         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19679
19680         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19681         local myDIR=$DIR/$tdir
19682
19683         mkdir -p $myDIR
19684         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19685         $LCTL set_param fail_loc=0x80001002
19686         createmany -o $myDIR/t- 10000
19687         $LCTL set_param fail_loc=0
19688         # The guard is current the largest FID holder
19689         touch $myDIR/guard
19690         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19691                     tr -d '[')
19692         local IDX=$(($SEQ % 64))
19693
19694         do_facet $SINGLEMDS sync
19695         # Make sure journal flushed.
19696         sleep 6
19697         local blk1=$(do_facet $SINGLEMDS \
19698                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19699                      grep Blockcount | awk '{print $4}')
19700
19701         # Remove old files, some OI blocks will become idle.
19702         unlinkmany $myDIR/t- 10000
19703
19704         # stop the MDT
19705         stop $SINGLEMDS || error "Fail to stop MDT."
19706         # remount the MDT
19707         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19708                 error "Fail to start MDT."
19709
19710         df $MOUNT || error "Fail to df."
19711         # Create new files, idle OI blocks should be reused.
19712         createmany -o $myDIR/t- 2000
19713         do_facet $SINGLEMDS sync
19714         # Make sure journal flushed.
19715         sleep 6
19716         local blk2=$(do_facet $SINGLEMDS \
19717                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19718                      grep Blockcount | awk '{print $4}')
19719
19720         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19721 }
19722 run_test 228b "idle OI blocks can be reused after MDT restart"
19723
19724 #LU-1881
19725 test_228c() {
19726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19727         remote_mds_nodsh && skip "remote MDS with nodsh"
19728         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19729
19730         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19731         local myDIR=$DIR/$tdir
19732
19733         mkdir -p $myDIR
19734         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19735         $LCTL set_param fail_loc=0x80001002
19736         # 20000 files can guarantee there are index nodes in the OI file
19737         createmany -o $myDIR/t- 20000
19738         $LCTL set_param fail_loc=0
19739         # The guard is current the largest FID holder
19740         touch $myDIR/guard
19741         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19742                     tr -d '[')
19743         local IDX=$(($SEQ % 64))
19744
19745         do_facet $SINGLEMDS sync
19746         # Make sure journal flushed.
19747         sleep 6
19748         local blk1=$(do_facet $SINGLEMDS \
19749                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19750                      grep Blockcount | awk '{print $4}')
19751
19752         # Remove old files, some OI blocks will become idle.
19753         unlinkmany $myDIR/t- 20000
19754         rm -f $myDIR/guard
19755         # The OI file should become empty now
19756
19757         # Create new files, idle OI blocks should be reused.
19758         createmany -o $myDIR/t- 2000
19759         do_facet $SINGLEMDS sync
19760         # Make sure journal flushed.
19761         sleep 6
19762         local blk2=$(do_facet $SINGLEMDS \
19763                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19764                      grep Blockcount | awk '{print $4}')
19765
19766         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19767 }
19768 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19769
19770 test_229() { # LU-2482, LU-3448
19771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19772         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19773         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19774                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19775
19776         rm -f $DIR/$tfile
19777
19778         # Create a file with a released layout and stripe count 2.
19779         $MULTIOP $DIR/$tfile H2c ||
19780                 error "failed to create file with released layout"
19781
19782         $LFS getstripe -v $DIR/$tfile
19783
19784         local pattern=$($LFS getstripe -L $DIR/$tfile)
19785         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19786
19787         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19788                 error "getstripe"
19789         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19790         stat $DIR/$tfile || error "failed to stat released file"
19791
19792         chown $RUNAS_ID $DIR/$tfile ||
19793                 error "chown $RUNAS_ID $DIR/$tfile failed"
19794
19795         chgrp $RUNAS_ID $DIR/$tfile ||
19796                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19797
19798         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19799         rm $DIR/$tfile || error "failed to remove released file"
19800 }
19801 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19802
19803 test_230a() {
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
19811         test_mkdir $DIR/$tdir
19812         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19813         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19814         [ $mdt_idx -ne 0 ] &&
19815                 error "create local directory on wrong MDT $mdt_idx"
19816
19817         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19818                         error "create remote directory failed"
19819         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19820         [ $mdt_idx -ne $MDTIDX ] &&
19821                 error "create remote directory on wrong MDT $mdt_idx"
19822
19823         createmany -o $DIR/$tdir/test_230/t- 10 ||
19824                 error "create files on remote directory failed"
19825         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19826         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19827         rm -r $DIR/$tdir || error "unlink remote directory failed"
19828 }
19829 run_test 230a "Create remote directory and files under the remote directory"
19830
19831 test_230b() {
19832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19834         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19835                 skip "Need MDS version at least 2.11.52"
19836
19837         local MDTIDX=1
19838         local mdt_index
19839         local i
19840         local file
19841         local pid
19842         local stripe_count
19843         local migrate_dir=$DIR/$tdir/migrate_dir
19844         local other_dir=$DIR/$tdir/other_dir
19845
19846         test_mkdir $DIR/$tdir
19847         test_mkdir -i0 -c1 $migrate_dir
19848         test_mkdir -i0 -c1 $other_dir
19849         for ((i=0; i<10; i++)); do
19850                 mkdir -p $migrate_dir/dir_${i}
19851                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19852                         error "create files under remote dir failed $i"
19853         done
19854
19855         cp /etc/passwd $migrate_dir/$tfile
19856         cp /etc/passwd $other_dir/$tfile
19857         chattr +SAD $migrate_dir
19858         chattr +SAD $migrate_dir/$tfile
19859
19860         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19861         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19862         local old_dir_mode=$(stat -c%f $migrate_dir)
19863         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19864
19865         mkdir -p $migrate_dir/dir_default_stripe2
19866         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19867         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19868
19869         mkdir -p $other_dir
19870         ln $migrate_dir/$tfile $other_dir/luna
19871         ln $migrate_dir/$tfile $migrate_dir/sofia
19872         ln $other_dir/$tfile $migrate_dir/david
19873         ln -s $migrate_dir/$tfile $other_dir/zachary
19874         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19875         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19876
19877         local len
19878         local lnktgt
19879
19880         # inline symlink
19881         for len in 58 59 60; do
19882                 lnktgt=$(str_repeat 'l' $len)
19883                 touch $migrate_dir/$lnktgt
19884                 ln -s $lnktgt $migrate_dir/${len}char_ln
19885         done
19886
19887         # PATH_MAX
19888         for len in 4094 4095; do
19889                 lnktgt=$(str_repeat 'l' $len)
19890                 ln -s $lnktgt $migrate_dir/${len}char_ln
19891         done
19892
19893         # NAME_MAX
19894         for len in 254 255; do
19895                 touch $migrate_dir/$(str_repeat 'l' $len)
19896         done
19897
19898         $LFS migrate -m $MDTIDX $migrate_dir ||
19899                 error "fails on migrating remote dir to MDT1"
19900
19901         echo "migratate to MDT1, then checking.."
19902         for ((i = 0; i < 10; i++)); do
19903                 for file in $(find $migrate_dir/dir_${i}); do
19904                         mdt_index=$($LFS getstripe -m $file)
19905                         # broken symlink getstripe will fail
19906                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19907                                 error "$file is not on MDT${MDTIDX}"
19908                 done
19909         done
19910
19911         # the multiple link file should still in MDT0
19912         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19913         [ $mdt_index == 0 ] ||
19914                 error "$file is not on MDT${MDTIDX}"
19915
19916         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19917         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19918                 error " expect $old_dir_flag get $new_dir_flag"
19919
19920         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19921         [ "$old_file_flag" = "$new_file_flag" ] ||
19922                 error " expect $old_file_flag get $new_file_flag"
19923
19924         local new_dir_mode=$(stat -c%f $migrate_dir)
19925         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19926                 error "expect mode $old_dir_mode get $new_dir_mode"
19927
19928         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19929         [ "$old_file_mode" = "$new_file_mode" ] ||
19930                 error "expect mode $old_file_mode get $new_file_mode"
19931
19932         diff /etc/passwd $migrate_dir/$tfile ||
19933                 error "$tfile different after migration"
19934
19935         diff /etc/passwd $other_dir/luna ||
19936                 error "luna different after migration"
19937
19938         diff /etc/passwd $migrate_dir/sofia ||
19939                 error "sofia different after migration"
19940
19941         diff /etc/passwd $migrate_dir/david ||
19942                 error "david different after migration"
19943
19944         diff /etc/passwd $other_dir/zachary ||
19945                 error "zachary different after migration"
19946
19947         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19948                 error "${tfile}_ln different after migration"
19949
19950         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19951                 error "${tfile}_ln_other different after migration"
19952
19953         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19954         [ $stripe_count = 2 ] ||
19955                 error "dir strpe_count $d != 2 after migration."
19956
19957         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19958         [ $stripe_count = 2 ] ||
19959                 error "file strpe_count $d != 2 after migration."
19960
19961         #migrate back to MDT0
19962         MDTIDX=0
19963
19964         $LFS migrate -m $MDTIDX $migrate_dir ||
19965                 error "fails on migrating remote dir to MDT0"
19966
19967         echo "migrate back to MDT0, checking.."
19968         for file in $(find $migrate_dir); do
19969                 mdt_index=$($LFS getstripe -m $file)
19970                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19971                         error "$file is not on MDT${MDTIDX}"
19972         done
19973
19974         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19975         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19976                 error " expect $old_dir_flag get $new_dir_flag"
19977
19978         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19979         [ "$old_file_flag" = "$new_file_flag" ] ||
19980                 error " expect $old_file_flag get $new_file_flag"
19981
19982         local new_dir_mode=$(stat -c%f $migrate_dir)
19983         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19984                 error "expect mode $old_dir_mode get $new_dir_mode"
19985
19986         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19987         [ "$old_file_mode" = "$new_file_mode" ] ||
19988                 error "expect mode $old_file_mode get $new_file_mode"
19989
19990         diff /etc/passwd ${migrate_dir}/$tfile ||
19991                 error "$tfile different after migration"
19992
19993         diff /etc/passwd ${other_dir}/luna ||
19994                 error "luna different after migration"
19995
19996         diff /etc/passwd ${migrate_dir}/sofia ||
19997                 error "sofia different after migration"
19998
19999         diff /etc/passwd ${other_dir}/zachary ||
20000                 error "zachary different after migration"
20001
20002         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20003                 error "${tfile}_ln different after migration"
20004
20005         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20006                 error "${tfile}_ln_other different after migration"
20007
20008         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20009         [ $stripe_count = 2 ] ||
20010                 error "dir strpe_count $d != 2 after migration."
20011
20012         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20013         [ $stripe_count = 2 ] ||
20014                 error "file strpe_count $d != 2 after migration."
20015
20016         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20017 }
20018 run_test 230b "migrate directory"
20019
20020 test_230c() {
20021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20023         remote_mds_nodsh && skip "remote MDS with nodsh"
20024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20025                 skip "Need MDS version at least 2.11.52"
20026
20027         local MDTIDX=1
20028         local total=3
20029         local mdt_index
20030         local file
20031         local migrate_dir=$DIR/$tdir/migrate_dir
20032
20033         #If migrating directory fails in the middle, all entries of
20034         #the directory is still accessiable.
20035         test_mkdir $DIR/$tdir
20036         test_mkdir -i0 -c1 $migrate_dir
20037         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20038         stat $migrate_dir
20039         createmany -o $migrate_dir/f $total ||
20040                 error "create files under ${migrate_dir} failed"
20041
20042         # fail after migrating top dir, and this will fail only once, so the
20043         # first sub file migration will fail (currently f3), others succeed.
20044         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20045         do_facet mds1 lctl set_param fail_loc=0x1801
20046         local t=$(ls $migrate_dir | wc -l)
20047         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20048                 error "migrate should fail"
20049         local u=$(ls $migrate_dir | wc -l)
20050         [ "$u" == "$t" ] || error "$u != $t during migration"
20051
20052         # add new dir/file should succeed
20053         mkdir $migrate_dir/dir ||
20054                 error "mkdir failed under migrating directory"
20055         touch $migrate_dir/file ||
20056                 error "create file failed under migrating directory"
20057
20058         # add file with existing name should fail
20059         for file in $migrate_dir/f*; do
20060                 stat $file > /dev/null || error "stat $file failed"
20061                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20062                         error "open(O_CREAT|O_EXCL) $file should fail"
20063                 $MULTIOP $file m && error "create $file should fail"
20064                 touch $DIR/$tdir/remote_dir/$tfile ||
20065                         error "touch $tfile failed"
20066                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20067                         error "link $file should fail"
20068                 mdt_index=$($LFS getstripe -m $file)
20069                 if [ $mdt_index == 0 ]; then
20070                         # file failed to migrate is not allowed to rename to
20071                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20072                                 error "rename to $file should fail"
20073                 else
20074                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20075                                 error "rename to $file failed"
20076                 fi
20077                 echo hello >> $file || error "write $file failed"
20078         done
20079
20080         # resume migration with different options should fail
20081         $LFS migrate -m 0 $migrate_dir &&
20082                 error "migrate -m 0 $migrate_dir should fail"
20083
20084         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20085                 error "migrate -c 2 $migrate_dir should fail"
20086
20087         # resume migration should succeed
20088         $LFS migrate -m $MDTIDX $migrate_dir ||
20089                 error "migrate $migrate_dir failed"
20090
20091         echo "Finish migration, then checking.."
20092         for file in $(find $migrate_dir); do
20093                 mdt_index=$($LFS getstripe -m $file)
20094                 [ $mdt_index == $MDTIDX ] ||
20095                         error "$file is not on MDT${MDTIDX}"
20096         done
20097
20098         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20099 }
20100 run_test 230c "check directory accessiblity if migration failed"
20101
20102 test_230d() {
20103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20105         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20106                 skip "Need MDS version at least 2.11.52"
20107         # LU-11235
20108         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20109
20110         local migrate_dir=$DIR/$tdir/migrate_dir
20111         local old_index
20112         local new_index
20113         local old_count
20114         local new_count
20115         local new_hash
20116         local mdt_index
20117         local i
20118         local j
20119
20120         old_index=$((RANDOM % MDSCOUNT))
20121         old_count=$((MDSCOUNT - old_index))
20122         new_index=$((RANDOM % MDSCOUNT))
20123         new_count=$((MDSCOUNT - new_index))
20124         new_hash=1 # for all_char
20125
20126         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20127         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20128
20129         test_mkdir $DIR/$tdir
20130         test_mkdir -i $old_index -c $old_count $migrate_dir
20131
20132         for ((i=0; i<100; i++)); do
20133                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20134                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20135                         error "create files under remote dir failed $i"
20136         done
20137
20138         echo -n "Migrate from MDT$old_index "
20139         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20140         echo -n "to MDT$new_index"
20141         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20142         echo
20143
20144         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20145         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20146                 error "migrate remote dir error"
20147
20148         echo "Finish migration, then checking.."
20149         for file in $(find $migrate_dir -maxdepth 1); do
20150                 mdt_index=$($LFS getstripe -m $file)
20151                 if [ $mdt_index -lt $new_index ] ||
20152                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20153                         error "$file is on MDT$mdt_index"
20154                 fi
20155         done
20156
20157         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20158 }
20159 run_test 230d "check migrate big directory"
20160
20161 test_230e() {
20162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20164         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20165                 skip "Need MDS version at least 2.11.52"
20166
20167         local i
20168         local j
20169         local a_fid
20170         local b_fid
20171
20172         mkdir_on_mdt0 $DIR/$tdir
20173         mkdir $DIR/$tdir/migrate_dir
20174         mkdir $DIR/$tdir/other_dir
20175         touch $DIR/$tdir/migrate_dir/a
20176         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20177         ls $DIR/$tdir/other_dir
20178
20179         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20180                 error "migrate dir fails"
20181
20182         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20183         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20184
20185         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20186         [ $mdt_index == 0 ] || error "a is not on MDT0"
20187
20188         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20189                 error "migrate dir fails"
20190
20191         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20192         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20193
20194         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20195         [ $mdt_index == 1 ] || error "a is not on MDT1"
20196
20197         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20198         [ $mdt_index == 1 ] || error "b is not on MDT1"
20199
20200         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20201         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20202
20203         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20204
20205         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20206 }
20207 run_test 230e "migrate mulitple local link files"
20208
20209 test_230f() {
20210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20212         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20213                 skip "Need MDS version at least 2.11.52"
20214
20215         local a_fid
20216         local ln_fid
20217
20218         mkdir -p $DIR/$tdir
20219         mkdir $DIR/$tdir/migrate_dir
20220         $LFS mkdir -i1 $DIR/$tdir/other_dir
20221         touch $DIR/$tdir/migrate_dir/a
20222         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20223         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20224         ls $DIR/$tdir/other_dir
20225
20226         # a should be migrated to MDT1, since no other links on MDT0
20227         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20228                 error "#1 migrate dir fails"
20229         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20230         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20231         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20232         [ $mdt_index == 1 ] || error "a is not on MDT1"
20233
20234         # a should stay on MDT1, because it is a mulitple link file
20235         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20236                 error "#2 migrate dir fails"
20237         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20238         [ $mdt_index == 1 ] || error "a is not on MDT1"
20239
20240         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20241                 error "#3 migrate dir fails"
20242
20243         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20244         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20245         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20246
20247         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20248         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20249
20250         # a should be migrated to MDT0, since no other links on MDT1
20251         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20252                 error "#4 migrate dir fails"
20253         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20254         [ $mdt_index == 0 ] || error "a is not on MDT0"
20255
20256         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20257 }
20258 run_test 230f "migrate mulitple remote link files"
20259
20260 test_230g() {
20261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20263         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20264                 skip "Need MDS version at least 2.11.52"
20265
20266         mkdir -p $DIR/$tdir/migrate_dir
20267
20268         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20269                 error "migrating dir to non-exist MDT succeeds"
20270         true
20271 }
20272 run_test 230g "migrate dir to non-exist MDT"
20273
20274 test_230h() {
20275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20278                 skip "Need MDS version at least 2.11.52"
20279
20280         local mdt_index
20281
20282         mkdir -p $DIR/$tdir/migrate_dir
20283
20284         $LFS migrate -m1 $DIR &&
20285                 error "migrating mountpoint1 should fail"
20286
20287         $LFS migrate -m1 $DIR/$tdir/.. &&
20288                 error "migrating mountpoint2 should fail"
20289
20290         # same as mv
20291         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20292                 error "migrating $tdir/migrate_dir/.. should fail"
20293
20294         true
20295 }
20296 run_test 230h "migrate .. and root"
20297
20298 test_230i() {
20299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20301         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20302                 skip "Need MDS version at least 2.11.52"
20303
20304         mkdir -p $DIR/$tdir/migrate_dir
20305
20306         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20307                 error "migration fails with a tailing slash"
20308
20309         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20310                 error "migration fails with two tailing slashes"
20311 }
20312 run_test 230i "lfs migrate -m tolerates trailing slashes"
20313
20314 test_230j() {
20315         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20316         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20317                 skip "Need MDS version at least 2.11.52"
20318
20319         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20320         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20321                 error "create $tfile failed"
20322         cat /etc/passwd > $DIR/$tdir/$tfile
20323
20324         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20325
20326         cmp /etc/passwd $DIR/$tdir/$tfile ||
20327                 error "DoM file mismatch after migration"
20328 }
20329 run_test 230j "DoM file data not changed after dir migration"
20330
20331 test_230k() {
20332         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20333         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20334                 skip "Need MDS version at least 2.11.56"
20335
20336         local total=20
20337         local files_on_starting_mdt=0
20338
20339         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20340         $LFS getdirstripe $DIR/$tdir
20341         for i in $(seq $total); do
20342                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20343                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20344                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20345         done
20346
20347         echo "$files_on_starting_mdt files on MDT0"
20348
20349         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20350         $LFS getdirstripe $DIR/$tdir
20351
20352         files_on_starting_mdt=0
20353         for i in $(seq $total); do
20354                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20355                         error "file $tfile.$i mismatch after migration"
20356                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20357                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20358         done
20359
20360         echo "$files_on_starting_mdt files on MDT1 after migration"
20361         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20362
20363         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20364         $LFS getdirstripe $DIR/$tdir
20365
20366         files_on_starting_mdt=0
20367         for i in $(seq $total); do
20368                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20369                         error "file $tfile.$i mismatch after 2nd migration"
20370                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20371                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20372         done
20373
20374         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20375         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20376
20377         true
20378 }
20379 run_test 230k "file data not changed after dir migration"
20380
20381 test_230l() {
20382         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20383         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20384                 skip "Need MDS version at least 2.11.56"
20385
20386         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20387         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20388                 error "create files under remote dir failed $i"
20389         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20390 }
20391 run_test 230l "readdir between MDTs won't crash"
20392
20393 test_230m() {
20394         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20395         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20396                 skip "Need MDS version at least 2.11.56"
20397
20398         local MDTIDX=1
20399         local mig_dir=$DIR/$tdir/migrate_dir
20400         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20401         local shortstr="b"
20402         local val
20403
20404         echo "Creating files and dirs with xattrs"
20405         test_mkdir $DIR/$tdir
20406         test_mkdir -i0 -c1 $mig_dir
20407         mkdir $mig_dir/dir
20408         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20409                 error "cannot set xattr attr1 on dir"
20410         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20411                 error "cannot set xattr attr2 on dir"
20412         touch $mig_dir/dir/f0
20413         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20414                 error "cannot set xattr attr1 on file"
20415         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20416                 error "cannot set xattr attr2 on file"
20417         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20418         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20419         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20420         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20421         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20422         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20423         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20424         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20425         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20426
20427         echo "Migrating to MDT1"
20428         $LFS migrate -m $MDTIDX $mig_dir ||
20429                 error "fails on migrating dir to MDT1"
20430
20431         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20432         echo "Checking xattrs"
20433         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20434         [ "$val" = $longstr ] ||
20435                 error "expecting xattr1 $longstr on dir, found $val"
20436         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20437         [ "$val" = $shortstr ] ||
20438                 error "expecting xattr2 $shortstr on dir, found $val"
20439         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20440         [ "$val" = $longstr ] ||
20441                 error "expecting xattr1 $longstr on file, found $val"
20442         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20443         [ "$val" = $shortstr ] ||
20444                 error "expecting xattr2 $shortstr on file, found $val"
20445 }
20446 run_test 230m "xattrs not changed after dir migration"
20447
20448 test_230n() {
20449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20450         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20451                 skip "Need MDS version at least 2.13.53"
20452
20453         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20454         cat /etc/hosts > $DIR/$tdir/$tfile
20455         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20456         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20457
20458         cmp /etc/hosts $DIR/$tdir/$tfile ||
20459                 error "File data mismatch after migration"
20460 }
20461 run_test 230n "Dir migration with mirrored file"
20462
20463 test_230o() {
20464         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20465         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20466                 skip "Need MDS version at least 2.13.52"
20467
20468         local mdts=$(comma_list $(mdts_nodes))
20469         local timeout=100
20470         local restripe_status
20471         local delta
20472         local i
20473
20474         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20475
20476         # in case "crush" hash type is not set
20477         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20478
20479         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20480                            mdt.*MDT0000.enable_dir_restripe)
20481         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20482         stack_trap "do_nodes $mdts $LCTL set_param \
20483                     mdt.*.enable_dir_restripe=$restripe_status"
20484
20485         mkdir $DIR/$tdir
20486         createmany -m $DIR/$tdir/f 100 ||
20487                 error "create files under remote dir failed $i"
20488         createmany -d $DIR/$tdir/d 100 ||
20489                 error "create dirs under remote dir failed $i"
20490
20491         for i in $(seq 2 $MDSCOUNT); do
20492                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20493                 $LFS setdirstripe -c $i $DIR/$tdir ||
20494                         error "split -c $i $tdir failed"
20495                 wait_update $HOSTNAME \
20496                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20497                         error "dir split not finished"
20498                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20499                         awk '/migrate/ {sum += $2} END { print sum }')
20500                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20501                 # delta is around total_files/stripe_count
20502                 (( $delta < 200 / (i - 1) + 4 )) ||
20503                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20504         done
20505 }
20506 run_test 230o "dir split"
20507
20508 test_230p() {
20509         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20510         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20511                 skip "Need MDS version at least 2.13.52"
20512
20513         local mdts=$(comma_list $(mdts_nodes))
20514         local timeout=100
20515         local restripe_status
20516         local delta
20517         local c
20518
20519         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20520
20521         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20522
20523         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20524                            mdt.*MDT0000.enable_dir_restripe)
20525         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20526         stack_trap "do_nodes $mdts $LCTL set_param \
20527                     mdt.*.enable_dir_restripe=$restripe_status"
20528
20529         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20530         createmany -m $DIR/$tdir/f 100 ||
20531                 error "create files under remote dir failed"
20532         createmany -d $DIR/$tdir/d 100 ||
20533                 error "create dirs under remote dir failed"
20534
20535         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20536                 local mdt_hash="crush"
20537
20538                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20539                 $LFS setdirstripe -c $c $DIR/$tdir ||
20540                         error "split -c $c $tdir failed"
20541                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20542                         mdt_hash="$mdt_hash,fixed"
20543                 elif [ $c -eq 1 ]; then
20544                         mdt_hash="none"
20545                 fi
20546                 wait_update $HOSTNAME \
20547                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20548                         error "dir merge not finished"
20549                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20550                         awk '/migrate/ {sum += $2} END { print sum }')
20551                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20552                 # delta is around total_files/stripe_count
20553                 (( delta < 200 / c + 4 )) ||
20554                         error "$delta files migrated >= $((200 / c + 4))"
20555         done
20556 }
20557 run_test 230p "dir merge"
20558
20559 test_230q() {
20560         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20561         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20562                 skip "Need MDS version at least 2.13.52"
20563
20564         local mdts=$(comma_list $(mdts_nodes))
20565         local saved_threshold=$(do_facet mds1 \
20566                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20567         local saved_delta=$(do_facet mds1 \
20568                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20569         local threshold=100
20570         local delta=2
20571         local total=0
20572         local stripe_count=0
20573         local stripe_index
20574         local nr_files
20575         local create
20576
20577         # test with fewer files on ZFS
20578         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20579
20580         stack_trap "do_nodes $mdts $LCTL set_param \
20581                     mdt.*.dir_split_count=$saved_threshold"
20582         stack_trap "do_nodes $mdts $LCTL set_param \
20583                     mdt.*.dir_split_delta=$saved_delta"
20584         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20585         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20586         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20587         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20588         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20589         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20590
20591         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20592         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20593
20594         create=$((threshold * 3 / 2))
20595         while [ $stripe_count -lt $MDSCOUNT ]; do
20596                 createmany -m $DIR/$tdir/f $total $create ||
20597                         error "create sub files failed"
20598                 stat $DIR/$tdir > /dev/null
20599                 total=$((total + create))
20600                 stripe_count=$((stripe_count + delta))
20601                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20602
20603                 wait_update $HOSTNAME \
20604                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20605                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20606
20607                 wait_update $HOSTNAME \
20608                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20609                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20610
20611                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20612                 echo "$nr_files/$total files on MDT$stripe_index after split"
20613                 # allow 10% margin of imbalance with crush hash
20614                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20615                         error "$nr_files files on MDT$stripe_index after split"
20616
20617                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20618                 [ $nr_files -eq $total ] ||
20619                         error "total sub files $nr_files != $total"
20620         done
20621
20622         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20623
20624         echo "fixed layout directory won't auto split"
20625         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20626         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20627                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20628         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20629                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20630 }
20631 run_test 230q "dir auto split"
20632
20633 test_230r() {
20634         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20635         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20636         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20637                 skip "Need MDS version at least 2.13.54"
20638
20639         # maximum amount of local locks:
20640         # parent striped dir - 2 locks
20641         # new stripe in parent to migrate to - 1 lock
20642         # source and target - 2 locks
20643         # Total 5 locks for regular file
20644         mkdir -p $DIR/$tdir
20645         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20646         touch $DIR/$tdir/dir1/eee
20647
20648         # create 4 hardlink for 4 more locks
20649         # Total: 9 locks > RS_MAX_LOCKS (8)
20650         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20651         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20652         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20653         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20654         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20655         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20656         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20657         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20658
20659         cancel_lru_locks mdc
20660
20661         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20662                 error "migrate dir fails"
20663
20664         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20665 }
20666 run_test 230r "migrate with too many local locks"
20667
20668 test_230s() {
20669         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20670                 skip "Need MDS version at least 2.14.52"
20671
20672         local mdts=$(comma_list $(mdts_nodes))
20673         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20674                                 mdt.*MDT0000.enable_dir_restripe)
20675
20676         stack_trap "do_nodes $mdts $LCTL set_param \
20677                     mdt.*.enable_dir_restripe=$restripe_status"
20678
20679         local st
20680         for st in 0 1; do
20681                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20682                 test_mkdir $DIR/$tdir
20683                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20684                         error "$LFS mkdir should return EEXIST if target exists"
20685                 rmdir $DIR/$tdir
20686         done
20687 }
20688 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20689
20690 test_230t()
20691 {
20692         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20693         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20694                 skip "Need MDS version at least 2.14.50"
20695
20696         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20697         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20698         $LFS project -p 1 -s $DIR/$tdir ||
20699                 error "set $tdir project id failed"
20700         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20701                 error "set subdir project id failed"
20702         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20703 }
20704 run_test 230t "migrate directory with project ID set"
20705
20706 test_230u()
20707 {
20708         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20709         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20710                 skip "Need MDS version at least 2.14.53"
20711
20712         local count
20713
20714         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20715         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20716         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20717         for i in $(seq 0 $((MDSCOUNT - 1))); do
20718                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20719                 echo "$count dirs migrated to MDT$i"
20720         done
20721         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20722         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20723 }
20724 run_test 230u "migrate directory by QOS"
20725
20726 test_230v()
20727 {
20728         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20729         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20730                 skip "Need MDS version at least 2.14.53"
20731
20732         local count
20733
20734         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20735         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20736         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20737         for i in $(seq 0 $((MDSCOUNT - 1))); do
20738                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20739                 echo "$count subdirs migrated to MDT$i"
20740                 (( i == 3 )) && (( count > 0 )) &&
20741                         error "subdir shouldn't be migrated to MDT3"
20742         done
20743         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20744         (( count == 3 )) || error "dirs migrated to $count MDTs"
20745 }
20746 run_test 230v "subdir migrated to the MDT where its parent is located"
20747
20748 test_230w() {
20749         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20750         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20751                 skip "Need MDS version at least 2.15.0"
20752
20753         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20754         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20755         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20756
20757         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20758                 error "migrate failed"
20759
20760         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20761                 error "$tdir stripe count mismatch"
20762
20763         for i in $(seq 0 9); do
20764                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20765                         error "d$i is striped"
20766         done
20767 }
20768 run_test 230w "non-recursive mode dir migration"
20769
20770 test_231a()
20771 {
20772         # For simplicity this test assumes that max_pages_per_rpc
20773         # is the same across all OSCs
20774         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20775         local bulk_size=$((max_pages * PAGE_SIZE))
20776         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20777                                        head -n 1)
20778
20779         mkdir -p $DIR/$tdir
20780         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20781                 error "failed to set stripe with -S ${brw_size}M option"
20782
20783         # clear the OSC stats
20784         $LCTL set_param osc.*.stats=0 &>/dev/null
20785         stop_writeback
20786
20787         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20788         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20789                 oflag=direct &>/dev/null || error "dd failed"
20790
20791         sync; sleep 1; sync # just to be safe
20792         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20793         if [ x$nrpcs != "x1" ]; then
20794                 $LCTL get_param osc.*.stats
20795                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20796         fi
20797
20798         start_writeback
20799         # Drop the OSC cache, otherwise we will read from it
20800         cancel_lru_locks osc
20801
20802         # clear the OSC stats
20803         $LCTL set_param osc.*.stats=0 &>/dev/null
20804
20805         # Client reads $bulk_size.
20806         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20807                 iflag=direct &>/dev/null || error "dd failed"
20808
20809         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20810         if [ x$nrpcs != "x1" ]; then
20811                 $LCTL get_param osc.*.stats
20812                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20813         fi
20814 }
20815 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20816
20817 test_231b() {
20818         mkdir -p $DIR/$tdir
20819         local i
20820         for i in {0..1023}; do
20821                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20822                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20823                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20824         done
20825         sync
20826 }
20827 run_test 231b "must not assert on fully utilized OST request buffer"
20828
20829 test_232a() {
20830         mkdir -p $DIR/$tdir
20831         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20832
20833         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20834         do_facet ost1 $LCTL set_param fail_loc=0x31c
20835
20836         # ignore dd failure
20837         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20838
20839         do_facet ost1 $LCTL set_param fail_loc=0
20840         umount_client $MOUNT || error "umount failed"
20841         mount_client $MOUNT || error "mount failed"
20842         stop ost1 || error "cannot stop ost1"
20843         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20844 }
20845 run_test 232a "failed lock should not block umount"
20846
20847 test_232b() {
20848         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20849                 skip "Need MDS version at least 2.10.58"
20850
20851         mkdir -p $DIR/$tdir
20852         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20853         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20854         sync
20855         cancel_lru_locks osc
20856
20857         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20858         do_facet ost1 $LCTL set_param fail_loc=0x31c
20859
20860         # ignore failure
20861         $LFS data_version $DIR/$tdir/$tfile || true
20862
20863         do_facet ost1 $LCTL set_param fail_loc=0
20864         umount_client $MOUNT || error "umount failed"
20865         mount_client $MOUNT || error "mount failed"
20866         stop ost1 || error "cannot stop ost1"
20867         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20868 }
20869 run_test 232b "failed data version lock should not block umount"
20870
20871 test_233a() {
20872         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20873                 skip "Need MDS version at least 2.3.64"
20874         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20875
20876         local fid=$($LFS path2fid $MOUNT)
20877
20878         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20879                 error "cannot access $MOUNT using its FID '$fid'"
20880 }
20881 run_test 233a "checking that OBF of the FS root succeeds"
20882
20883 test_233b() {
20884         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20885                 skip "Need MDS version at least 2.5.90"
20886         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20887
20888         local fid=$($LFS path2fid $MOUNT/.lustre)
20889
20890         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20891                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20892
20893         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20894         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20895                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20896 }
20897 run_test 233b "checking that OBF of the FS .lustre succeeds"
20898
20899 test_234() {
20900         local p="$TMP/sanityN-$TESTNAME.parameters"
20901         save_lustre_params client "llite.*.xattr_cache" > $p
20902         lctl set_param llite.*.xattr_cache 1 ||
20903                 skip_env "xattr cache is not supported"
20904
20905         mkdir -p $DIR/$tdir || error "mkdir failed"
20906         touch $DIR/$tdir/$tfile || error "touch failed"
20907         # OBD_FAIL_LLITE_XATTR_ENOMEM
20908         $LCTL set_param fail_loc=0x1405
20909         getfattr -n user.attr $DIR/$tdir/$tfile &&
20910                 error "getfattr should have failed with ENOMEM"
20911         $LCTL set_param fail_loc=0x0
20912         rm -rf $DIR/$tdir
20913
20914         restore_lustre_params < $p
20915         rm -f $p
20916 }
20917 run_test 234 "xattr cache should not crash on ENOMEM"
20918
20919 test_235() {
20920         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20921                 skip "Need MDS version at least 2.4.52"
20922
20923         flock_deadlock $DIR/$tfile
20924         local RC=$?
20925         case $RC in
20926                 0)
20927                 ;;
20928                 124) error "process hangs on a deadlock"
20929                 ;;
20930                 *) error "error executing flock_deadlock $DIR/$tfile"
20931                 ;;
20932         esac
20933 }
20934 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20935
20936 #LU-2935
20937 test_236() {
20938         check_swap_layouts_support
20939
20940         local ref1=/etc/passwd
20941         local ref2=/etc/group
20942         local file1=$DIR/$tdir/f1
20943         local file2=$DIR/$tdir/f2
20944
20945         test_mkdir -c1 $DIR/$tdir
20946         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20947         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20948         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20949         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20950         local fd=$(free_fd)
20951         local cmd="exec $fd<>$file2"
20952         eval $cmd
20953         rm $file2
20954         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20955                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20956         cmd="exec $fd>&-"
20957         eval $cmd
20958         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20959
20960         #cleanup
20961         rm -rf $DIR/$tdir
20962 }
20963 run_test 236 "Layout swap on open unlinked file"
20964
20965 # LU-4659 linkea consistency
20966 test_238() {
20967         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20968                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20969                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20970                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20971
20972         touch $DIR/$tfile
20973         ln $DIR/$tfile $DIR/$tfile.lnk
20974         touch $DIR/$tfile.new
20975         mv $DIR/$tfile.new $DIR/$tfile
20976         local fid1=$($LFS path2fid $DIR/$tfile)
20977         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20978         local path1=$($LFS fid2path $FSNAME "$fid1")
20979         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20980         local path2=$($LFS fid2path $FSNAME "$fid2")
20981         [ $tfile.lnk == $path2 ] ||
20982                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20983         rm -f $DIR/$tfile*
20984 }
20985 run_test 238 "Verify linkea consistency"
20986
20987 test_239A() { # was test_239
20988         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20989                 skip "Need MDS version at least 2.5.60"
20990
20991         local list=$(comma_list $(mdts_nodes))
20992
20993         mkdir -p $DIR/$tdir
20994         createmany -o $DIR/$tdir/f- 5000
20995         unlinkmany $DIR/$tdir/f- 5000
20996         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20997                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20998         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20999                         osp.*MDT*.sync_in_flight" | calc_sum)
21000         [ "$changes" -eq 0 ] || error "$changes not synced"
21001 }
21002 run_test 239A "osp_sync test"
21003
21004 test_239a() { #LU-5297
21005         remote_mds_nodsh && skip "remote MDS with nodsh"
21006
21007         touch $DIR/$tfile
21008         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21009         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21010         chgrp $RUNAS_GID $DIR/$tfile
21011         wait_delete_completed
21012 }
21013 run_test 239a "process invalid osp sync record correctly"
21014
21015 test_239b() { #LU-5297
21016         remote_mds_nodsh && skip "remote MDS with nodsh"
21017
21018         touch $DIR/$tfile1
21019         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21020         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21021         chgrp $RUNAS_GID $DIR/$tfile1
21022         wait_delete_completed
21023         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21024         touch $DIR/$tfile2
21025         chgrp $RUNAS_GID $DIR/$tfile2
21026         wait_delete_completed
21027 }
21028 run_test 239b "process osp sync record with ENOMEM error correctly"
21029
21030 test_240() {
21031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21032         remote_mds_nodsh && skip "remote MDS with nodsh"
21033
21034         mkdir -p $DIR/$tdir
21035
21036         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21037                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21038         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21039                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21040
21041         umount_client $MOUNT || error "umount failed"
21042         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21043         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21044         mount_client $MOUNT || error "failed to mount client"
21045
21046         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21047         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21048 }
21049 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21050
21051 test_241_bio() {
21052         local count=$1
21053         local bsize=$2
21054
21055         for LOOP in $(seq $count); do
21056                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21057                 cancel_lru_locks $OSC || true
21058         done
21059 }
21060
21061 test_241_dio() {
21062         local count=$1
21063         local bsize=$2
21064
21065         for LOOP in $(seq $1); do
21066                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21067                         2>/dev/null
21068         done
21069 }
21070
21071 test_241a() { # was test_241
21072         local bsize=$PAGE_SIZE
21073
21074         (( bsize < 40960 )) && bsize=40960
21075         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21076         ls -la $DIR/$tfile
21077         cancel_lru_locks $OSC
21078         test_241_bio 1000 $bsize &
21079         PID=$!
21080         test_241_dio 1000 $bsize
21081         wait $PID
21082 }
21083 run_test 241a "bio vs dio"
21084
21085 test_241b() {
21086         local bsize=$PAGE_SIZE
21087
21088         (( bsize < 40960 )) && bsize=40960
21089         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21090         ls -la $DIR/$tfile
21091         test_241_dio 1000 $bsize &
21092         PID=$!
21093         test_241_dio 1000 $bsize
21094         wait $PID
21095 }
21096 run_test 241b "dio vs dio"
21097
21098 test_242() {
21099         remote_mds_nodsh && skip "remote MDS with nodsh"
21100
21101         mkdir_on_mdt0 $DIR/$tdir
21102         touch $DIR/$tdir/$tfile
21103
21104         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21105         do_facet mds1 lctl set_param fail_loc=0x105
21106         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21107
21108         do_facet mds1 lctl set_param fail_loc=0
21109         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21110 }
21111 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21112
21113 test_243()
21114 {
21115         test_mkdir $DIR/$tdir
21116         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21117 }
21118 run_test 243 "various group lock tests"
21119
21120 test_244a()
21121 {
21122         test_mkdir $DIR/$tdir
21123         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21124         sendfile_grouplock $DIR/$tdir/$tfile || \
21125                 error "sendfile+grouplock failed"
21126         rm -rf $DIR/$tdir
21127 }
21128 run_test 244a "sendfile with group lock tests"
21129
21130 test_244b()
21131 {
21132         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21133
21134         local threads=50
21135         local size=$((1024*1024))
21136
21137         test_mkdir $DIR/$tdir
21138         for i in $(seq 1 $threads); do
21139                 local file=$DIR/$tdir/file_$((i / 10))
21140                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21141                 local pids[$i]=$!
21142         done
21143         for i in $(seq 1 $threads); do
21144                 wait ${pids[$i]}
21145         done
21146 }
21147 run_test 244b "multi-threaded write with group lock"
21148
21149 test_245a() {
21150         local flagname="multi_mod_rpcs"
21151         local connect_data_name="max_mod_rpcs"
21152         local out
21153
21154         # check if multiple modify RPCs flag is set
21155         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21156                 grep "connect_flags:")
21157         echo "$out"
21158
21159         echo "$out" | grep -qw $flagname
21160         if [ $? -ne 0 ]; then
21161                 echo "connect flag $flagname is not set"
21162                 return
21163         fi
21164
21165         # check if multiple modify RPCs data is set
21166         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21167         echo "$out"
21168
21169         echo "$out" | grep -qw $connect_data_name ||
21170                 error "import should have connect data $connect_data_name"
21171 }
21172 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21173
21174 test_245b() {
21175         local flagname="multi_mod_rpcs"
21176         local connect_data_name="max_mod_rpcs"
21177         local out
21178
21179         remote_mds_nodsh && skip "remote MDS with nodsh"
21180         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21181
21182         # check if multiple modify RPCs flag is set
21183         out=$(do_facet mds1 \
21184               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21185               grep "connect_flags:")
21186         echo "$out"
21187
21188         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21189
21190         # check if multiple modify RPCs data is set
21191         out=$(do_facet mds1 \
21192               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21193
21194         [[ "$out" =~ $connect_data_name ]] ||
21195                 {
21196                         echo "$out"
21197                         error "missing connect data $connect_data_name"
21198                 }
21199 }
21200 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21201
21202 cleanup_247() {
21203         local submount=$1
21204
21205         trap 0
21206         umount_client $submount
21207         rmdir $submount
21208 }
21209
21210 test_247a() {
21211         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21212                 grep -q subtree ||
21213                 skip_env "Fileset feature is not supported"
21214
21215         local submount=${MOUNT}_$tdir
21216
21217         mkdir $MOUNT/$tdir
21218         mkdir -p $submount || error "mkdir $submount failed"
21219         FILESET="$FILESET/$tdir" mount_client $submount ||
21220                 error "mount $submount failed"
21221         trap "cleanup_247 $submount" EXIT
21222         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21223         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21224                 error "read $MOUNT/$tdir/$tfile failed"
21225         cleanup_247 $submount
21226 }
21227 run_test 247a "mount subdir as fileset"
21228
21229 test_247b() {
21230         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21231                 skip_env "Fileset feature is not supported"
21232
21233         local submount=${MOUNT}_$tdir
21234
21235         rm -rf $MOUNT/$tdir
21236         mkdir -p $submount || error "mkdir $submount failed"
21237         SKIP_FILESET=1
21238         FILESET="$FILESET/$tdir" mount_client $submount &&
21239                 error "mount $submount should fail"
21240         rmdir $submount
21241 }
21242 run_test 247b "mount subdir that dose not exist"
21243
21244 test_247c() {
21245         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21246                 skip_env "Fileset feature is not supported"
21247
21248         local submount=${MOUNT}_$tdir
21249
21250         mkdir -p $MOUNT/$tdir/dir1
21251         mkdir -p $submount || error "mkdir $submount failed"
21252         trap "cleanup_247 $submount" EXIT
21253         FILESET="$FILESET/$tdir" mount_client $submount ||
21254                 error "mount $submount failed"
21255         local fid=$($LFS path2fid $MOUNT/)
21256         $LFS fid2path $submount $fid && error "fid2path should fail"
21257         cleanup_247 $submount
21258 }
21259 run_test 247c "running fid2path outside subdirectory root"
21260
21261 test_247d() {
21262         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21263                 skip "Fileset feature is not supported"
21264
21265         local submount=${MOUNT}_$tdir
21266
21267         mkdir -p $MOUNT/$tdir/dir1
21268         mkdir -p $submount || error "mkdir $submount failed"
21269         FILESET="$FILESET/$tdir" mount_client $submount ||
21270                 error "mount $submount failed"
21271         trap "cleanup_247 $submount" EXIT
21272
21273         local td=$submount/dir1
21274         local fid=$($LFS path2fid $td)
21275         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21276
21277         # check that we get the same pathname back
21278         local rootpath
21279         local found
21280         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21281                 echo "$rootpath $fid"
21282                 found=$($LFS fid2path $rootpath "$fid")
21283                 [ -n "$found" ] || error "fid2path should succeed"
21284                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21285         done
21286         # check wrong root path format
21287         rootpath=$submount"_wrong"
21288         found=$($LFS fid2path $rootpath "$fid")
21289         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21290
21291         cleanup_247 $submount
21292 }
21293 run_test 247d "running fid2path inside subdirectory root"
21294
21295 # LU-8037
21296 test_247e() {
21297         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21298                 grep -q subtree ||
21299                 skip "Fileset feature is not supported"
21300
21301         local submount=${MOUNT}_$tdir
21302
21303         mkdir $MOUNT/$tdir
21304         mkdir -p $submount || error "mkdir $submount failed"
21305         FILESET="$FILESET/.." mount_client $submount &&
21306                 error "mount $submount should fail"
21307         rmdir $submount
21308 }
21309 run_test 247e "mount .. as fileset"
21310
21311 test_247f() {
21312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21313         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21314                 skip "Need at least version 2.13.52"
21315         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21316                 skip "Need at least version 2.14.50"
21317         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21318                 grep -q subtree ||
21319                 skip "Fileset feature is not supported"
21320
21321         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21322         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21323                 error "mkdir remote failed"
21324         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21325                 error "mkdir remote/subdir failed"
21326         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21327                 error "mkdir striped failed"
21328         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21329
21330         local submount=${MOUNT}_$tdir
21331
21332         mkdir -p $submount || error "mkdir $submount failed"
21333         stack_trap "rmdir $submount"
21334
21335         local dir
21336         local stat
21337         local fileset=$FILESET
21338         local mdts=$(comma_list $(mdts_nodes))
21339
21340         stat=$(do_facet mds1 $LCTL get_param -n \
21341                 mdt.*MDT0000.enable_remote_subdir_mount)
21342         stack_trap "do_nodes $mdts $LCTL set_param \
21343                 mdt.*.enable_remote_subdir_mount=$stat"
21344
21345         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21346         stack_trap "umount_client $submount"
21347         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21348                 error "mount remote dir $dir should fail"
21349
21350         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21351                 $tdir/striped/. ; do
21352                 FILESET="$fileset/$dir" mount_client $submount ||
21353                         error "mount $dir failed"
21354                 umount_client $submount
21355         done
21356
21357         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21358         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21359                 error "mount $tdir/remote failed"
21360 }
21361 run_test 247f "mount striped or remote directory as fileset"
21362
21363 test_247g() {
21364         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21365         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21366                 skip "Need at least version 2.14.50"
21367
21368         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21369                 error "mkdir $tdir failed"
21370         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21371
21372         local submount=${MOUNT}_$tdir
21373
21374         mkdir -p $submount || error "mkdir $submount failed"
21375         stack_trap "rmdir $submount"
21376
21377         FILESET="$fileset/$tdir" mount_client $submount ||
21378                 error "mount $dir failed"
21379         stack_trap "umount $submount"
21380
21381         local mdts=$(comma_list $(mdts_nodes))
21382
21383         local nrpcs
21384
21385         stat $submount > /dev/null
21386         cancel_lru_locks $MDC
21387         stat $submount > /dev/null
21388         stat $submount/$tfile > /dev/null
21389         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21390         stat $submount/$tfile > /dev/null
21391         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21392                 awk '/getattr/ {sum += $2} END {print sum}')
21393
21394         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21395 }
21396 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21397
21398 test_248a() {
21399         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21400         [ -z "$fast_read_sav" ] && skip "no fast read support"
21401
21402         # create a large file for fast read verification
21403         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21404
21405         # make sure the file is created correctly
21406         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21407                 { rm -f $DIR/$tfile; skip "file creation error"; }
21408
21409         echo "Test 1: verify that fast read is 4 times faster on cache read"
21410
21411         # small read with fast read enabled
21412         $LCTL set_param -n llite.*.fast_read=1
21413         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21414                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21415                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21416         # small read with fast read disabled
21417         $LCTL set_param -n llite.*.fast_read=0
21418         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21419                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21420                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21421
21422         # verify that fast read is 4 times faster for cache read
21423         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21424                 error_not_in_vm "fast read was not 4 times faster: " \
21425                            "$t_fast vs $t_slow"
21426
21427         echo "Test 2: verify the performance between big and small read"
21428         $LCTL set_param -n llite.*.fast_read=1
21429
21430         # 1k non-cache read
21431         cancel_lru_locks osc
21432         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21433                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21434                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21435
21436         # 1M non-cache read
21437         cancel_lru_locks osc
21438         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21439                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21440                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21441
21442         # verify that big IO is not 4 times faster than small IO
21443         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21444                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21445
21446         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21447         rm -f $DIR/$tfile
21448 }
21449 run_test 248a "fast read verification"
21450
21451 test_248b() {
21452         # Default short_io_bytes=16384, try both smaller and larger sizes.
21453         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21454         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21455         echo "bs=53248 count=113 normal buffered write"
21456         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21457                 error "dd of initial data file failed"
21458         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21459
21460         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21461         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21462                 error "dd with sync normal writes failed"
21463         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21464
21465         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21466         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21467                 error "dd with sync small writes failed"
21468         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21469
21470         cancel_lru_locks osc
21471
21472         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21473         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21474         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21475         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21476                 iflag=direct || error "dd with O_DIRECT small read failed"
21477         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21478         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21479                 error "compare $TMP/$tfile.1 failed"
21480
21481         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21482         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21483
21484         # just to see what the maximum tunable value is, and test parsing
21485         echo "test invalid parameter 2MB"
21486         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21487                 error "too-large short_io_bytes allowed"
21488         echo "test maximum parameter 512KB"
21489         # if we can set a larger short_io_bytes, run test regardless of version
21490         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21491                 # older clients may not allow setting it this large, that's OK
21492                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21493                         skip "Need at least client version 2.13.50"
21494                 error "medium short_io_bytes failed"
21495         fi
21496         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21497         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21498
21499         echo "test large parameter 64KB"
21500         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21501         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21502
21503         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21504         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21505                 error "dd with sync large writes failed"
21506         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21507
21508         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21509         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21510         num=$((113 * 4096 / PAGE_SIZE))
21511         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21512         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21513                 error "dd with O_DIRECT large writes failed"
21514         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21515                 error "compare $DIR/$tfile.3 failed"
21516
21517         cancel_lru_locks osc
21518
21519         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21520         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21521                 error "dd with O_DIRECT large read failed"
21522         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21523                 error "compare $TMP/$tfile.2 failed"
21524
21525         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21526         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21527                 error "dd with O_DIRECT large read failed"
21528         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21529                 error "compare $TMP/$tfile.3 failed"
21530 }
21531 run_test 248b "test short_io read and write for both small and large sizes"
21532
21533 test_249() { # LU-7890
21534         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21535                 skip "Need at least version 2.8.54"
21536
21537         rm -f $DIR/$tfile
21538         $LFS setstripe -c 1 $DIR/$tfile
21539         # Offset 2T == 4k * 512M
21540         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21541                 error "dd to 2T offset failed"
21542 }
21543 run_test 249 "Write above 2T file size"
21544
21545 test_250() {
21546         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21547          && skip "no 16TB file size limit on ZFS"
21548
21549         $LFS setstripe -c 1 $DIR/$tfile
21550         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21551         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21552         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21553         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21554                 conv=notrunc,fsync && error "append succeeded"
21555         return 0
21556 }
21557 run_test 250 "Write above 16T limit"
21558
21559 test_251() {
21560         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21561
21562         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21563         #Skip once - writing the first stripe will succeed
21564         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21565         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21566                 error "short write happened"
21567
21568         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21569         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21570                 error "short read happened"
21571
21572         rm -f $DIR/$tfile
21573 }
21574 run_test 251 "Handling short read and write correctly"
21575
21576 test_252() {
21577         remote_mds_nodsh && skip "remote MDS with nodsh"
21578         remote_ost_nodsh && skip "remote OST with nodsh"
21579         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21580                 skip_env "ldiskfs only test"
21581         fi
21582
21583         local tgt
21584         local dev
21585         local out
21586         local uuid
21587         local num
21588         local gen
21589
21590         # check lr_reader on OST0000
21591         tgt=ost1
21592         dev=$(facet_device $tgt)
21593         out=$(do_facet $tgt $LR_READER $dev)
21594         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21595         echo "$out"
21596         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21597         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21598                 error "Invalid uuid returned by $LR_READER on target $tgt"
21599         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21600
21601         # check lr_reader -c on MDT0000
21602         tgt=mds1
21603         dev=$(facet_device $tgt)
21604         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21605                 skip "$LR_READER does not support additional options"
21606         fi
21607         out=$(do_facet $tgt $LR_READER -c $dev)
21608         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21609         echo "$out"
21610         num=$(echo "$out" | grep -c "mdtlov")
21611         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21612                 error "Invalid number of mdtlov clients returned by $LR_READER"
21613         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21614
21615         # check lr_reader -cr on MDT0000
21616         out=$(do_facet $tgt $LR_READER -cr $dev)
21617         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21618         echo "$out"
21619         echo "$out" | grep -q "^reply_data:$" ||
21620                 error "$LR_READER should have returned 'reply_data' section"
21621         num=$(echo "$out" | grep -c "client_generation")
21622         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21623 }
21624 run_test 252 "check lr_reader tool"
21625
21626 test_253() {
21627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21628         remote_mds_nodsh && skip "remote MDS with nodsh"
21629         remote_mgs_nodsh && skip "remote MGS with nodsh"
21630
21631         local ostidx=0
21632         local rc=0
21633         local ost_name=$(ostname_from_index $ostidx)
21634
21635         # on the mdt's osc
21636         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21637         do_facet $SINGLEMDS $LCTL get_param -n \
21638                 osp.$mdtosc_proc1.reserved_mb_high ||
21639                 skip  "remote MDS does not support reserved_mb_high"
21640
21641         rm -rf $DIR/$tdir
21642         wait_mds_ost_sync
21643         wait_delete_completed
21644         mkdir $DIR/$tdir
21645
21646         pool_add $TESTNAME || error "Pool creation failed"
21647         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21648
21649         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21650                 error "Setstripe failed"
21651
21652         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21653
21654         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21655                     grep "watermarks")
21656         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21657
21658         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21659                         osp.$mdtosc_proc1.prealloc_status)
21660         echo "prealloc_status $oa_status"
21661
21662         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21663                 error "File creation should fail"
21664
21665         #object allocation was stopped, but we still able to append files
21666         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21667                 oflag=append || error "Append failed"
21668
21669         rm -f $DIR/$tdir/$tfile.0
21670
21671         # For this test, we want to delete the files we created to go out of
21672         # space but leave the watermark, so we remain nearly out of space
21673         ost_watermarks_enospc_delete_files $tfile $ostidx
21674
21675         wait_delete_completed
21676
21677         sleep_maxage
21678
21679         for i in $(seq 10 12); do
21680                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21681                         2>/dev/null || error "File creation failed after rm"
21682         done
21683
21684         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21685                         osp.$mdtosc_proc1.prealloc_status)
21686         echo "prealloc_status $oa_status"
21687
21688         if (( oa_status != 0 )); then
21689                 error "Object allocation still disable after rm"
21690         fi
21691 }
21692 run_test 253 "Check object allocation limit"
21693
21694 test_254() {
21695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21696         remote_mds_nodsh && skip "remote MDS with nodsh"
21697
21698         local mdt=$(facet_svc $SINGLEMDS)
21699
21700         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21701                 skip "MDS does not support changelog_size"
21702
21703         local cl_user
21704
21705         changelog_register || error "changelog_register failed"
21706
21707         changelog_clear 0 || error "changelog_clear failed"
21708
21709         local size1=$(do_facet $SINGLEMDS \
21710                       $LCTL get_param -n mdd.$mdt.changelog_size)
21711         echo "Changelog size $size1"
21712
21713         rm -rf $DIR/$tdir
21714         $LFS mkdir -i 0 $DIR/$tdir
21715         # change something
21716         mkdir -p $DIR/$tdir/pics/2008/zachy
21717         touch $DIR/$tdir/pics/2008/zachy/timestamp
21718         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21719         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21720         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21721         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21722         rm $DIR/$tdir/pics/desktop.jpg
21723
21724         local size2=$(do_facet $SINGLEMDS \
21725                       $LCTL get_param -n mdd.$mdt.changelog_size)
21726         echo "Changelog size after work $size2"
21727
21728         (( $size2 > $size1 )) ||
21729                 error "new Changelog size=$size2 less than old size=$size1"
21730 }
21731 run_test 254 "Check changelog size"
21732
21733 ladvise_no_type()
21734 {
21735         local type=$1
21736         local file=$2
21737
21738         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21739                 awk -F: '{print $2}' | grep $type > /dev/null
21740         if [ $? -ne 0 ]; then
21741                 return 0
21742         fi
21743         return 1
21744 }
21745
21746 ladvise_no_ioctl()
21747 {
21748         local file=$1
21749
21750         lfs ladvise -a willread $file > /dev/null 2>&1
21751         if [ $? -eq 0 ]; then
21752                 return 1
21753         fi
21754
21755         lfs ladvise -a willread $file 2>&1 |
21756                 grep "Inappropriate ioctl for device" > /dev/null
21757         if [ $? -eq 0 ]; then
21758                 return 0
21759         fi
21760         return 1
21761 }
21762
21763 percent() {
21764         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21765 }
21766
21767 # run a random read IO workload
21768 # usage: random_read_iops <filename> <filesize> <iosize>
21769 random_read_iops() {
21770         local file=$1
21771         local fsize=$2
21772         local iosize=${3:-4096}
21773
21774         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21775                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21776 }
21777
21778 drop_file_oss_cache() {
21779         local file="$1"
21780         local nodes="$2"
21781
21782         $LFS ladvise -a dontneed $file 2>/dev/null ||
21783                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21784 }
21785
21786 ladvise_willread_performance()
21787 {
21788         local repeat=10
21789         local average_origin=0
21790         local average_cache=0
21791         local average_ladvise=0
21792
21793         for ((i = 1; i <= $repeat; i++)); do
21794                 echo "Iter $i/$repeat: reading without willread hint"
21795                 cancel_lru_locks osc
21796                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21797                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21798                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21799                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21800
21801                 cancel_lru_locks osc
21802                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21803                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21804                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21805
21806                 cancel_lru_locks osc
21807                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21808                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21809                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21810                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21811                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21812         done
21813         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21814         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21815         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21816
21817         speedup_cache=$(percent $average_cache $average_origin)
21818         speedup_ladvise=$(percent $average_ladvise $average_origin)
21819
21820         echo "Average uncached read: $average_origin"
21821         echo "Average speedup with OSS cached read: " \
21822                 "$average_cache = +$speedup_cache%"
21823         echo "Average speedup with ladvise willread: " \
21824                 "$average_ladvise = +$speedup_ladvise%"
21825
21826         local lowest_speedup=20
21827         if (( ${average_cache%.*} < $lowest_speedup )); then
21828                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21829                      " got $average_cache%. Skipping ladvise willread check."
21830                 return 0
21831         fi
21832
21833         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21834         # it is still good to run until then to exercise 'ladvise willread'
21835         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21836                 [ "$ost1_FSTYPE" = "zfs" ] &&
21837                 echo "osd-zfs does not support dontneed or drop_caches" &&
21838                 return 0
21839
21840         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21841         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21842                 error_not_in_vm "Speedup with willread is less than " \
21843                         "$lowest_speedup%, got $average_ladvise%"
21844 }
21845
21846 test_255a() {
21847         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21848                 skip "lustre < 2.8.54 does not support ladvise "
21849         remote_ost_nodsh && skip "remote OST with nodsh"
21850
21851         stack_trap "rm -f $DIR/$tfile"
21852         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21853
21854         ladvise_no_type willread $DIR/$tfile &&
21855                 skip "willread ladvise is not supported"
21856
21857         ladvise_no_ioctl $DIR/$tfile &&
21858                 skip "ladvise ioctl is not supported"
21859
21860         local size_mb=100
21861         local size=$((size_mb * 1048576))
21862         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21863                 error "dd to $DIR/$tfile failed"
21864
21865         lfs ladvise -a willread $DIR/$tfile ||
21866                 error "Ladvise failed with no range argument"
21867
21868         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21869                 error "Ladvise failed with no -l or -e argument"
21870
21871         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21872                 error "Ladvise failed with only -e argument"
21873
21874         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21875                 error "Ladvise failed with only -l argument"
21876
21877         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21878                 error "End offset should not be smaller than start offset"
21879
21880         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21881                 error "End offset should not be equal to start offset"
21882
21883         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21884                 error "Ladvise failed with overflowing -s argument"
21885
21886         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21887                 error "Ladvise failed with overflowing -e argument"
21888
21889         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21890                 error "Ladvise failed with overflowing -l argument"
21891
21892         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21893                 error "Ladvise succeeded with conflicting -l and -e arguments"
21894
21895         echo "Synchronous ladvise should wait"
21896         local delay=4
21897 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21898         do_nodes $(comma_list $(osts_nodes)) \
21899                 $LCTL set_param fail_val=$delay fail_loc=0x237
21900
21901         local start_ts=$SECONDS
21902         lfs ladvise -a willread $DIR/$tfile ||
21903                 error "Ladvise failed with no range argument"
21904         local end_ts=$SECONDS
21905         local inteval_ts=$((end_ts - start_ts))
21906
21907         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21908                 error "Synchronous advice didn't wait reply"
21909         fi
21910
21911         echo "Asynchronous ladvise shouldn't wait"
21912         local start_ts=$SECONDS
21913         lfs ladvise -a willread -b $DIR/$tfile ||
21914                 error "Ladvise failed with no range argument"
21915         local end_ts=$SECONDS
21916         local inteval_ts=$((end_ts - start_ts))
21917
21918         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21919                 error "Asynchronous advice blocked"
21920         fi
21921
21922         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21923         ladvise_willread_performance
21924 }
21925 run_test 255a "check 'lfs ladvise -a willread'"
21926
21927 facet_meminfo() {
21928         local facet=$1
21929         local info=$2
21930
21931         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21932 }
21933
21934 test_255b() {
21935         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21936                 skip "lustre < 2.8.54 does not support ladvise "
21937         remote_ost_nodsh && skip "remote OST with nodsh"
21938
21939         stack_trap "rm -f $DIR/$tfile"
21940         lfs setstripe -c 1 -i 0 $DIR/$tfile
21941
21942         ladvise_no_type dontneed $DIR/$tfile &&
21943                 skip "dontneed ladvise is not supported"
21944
21945         ladvise_no_ioctl $DIR/$tfile &&
21946                 skip "ladvise ioctl is not supported"
21947
21948         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21949                 [ "$ost1_FSTYPE" = "zfs" ] &&
21950                 skip "zfs-osd does not support 'ladvise dontneed'"
21951
21952         local size_mb=100
21953         local size=$((size_mb * 1048576))
21954         # In order to prevent disturbance of other processes, only check 3/4
21955         # of the memory usage
21956         local kibibytes=$((size_mb * 1024 * 3 / 4))
21957
21958         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21959                 error "dd to $DIR/$tfile failed"
21960
21961         #force write to complete before dropping OST cache & checking memory
21962         sync
21963
21964         local total=$(facet_meminfo ost1 MemTotal)
21965         echo "Total memory: $total KiB"
21966
21967         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21968         local before_read=$(facet_meminfo ost1 Cached)
21969         echo "Cache used before read: $before_read KiB"
21970
21971         lfs ladvise -a willread $DIR/$tfile ||
21972                 error "Ladvise willread failed"
21973         local after_read=$(facet_meminfo ost1 Cached)
21974         echo "Cache used after read: $after_read KiB"
21975
21976         lfs ladvise -a dontneed $DIR/$tfile ||
21977                 error "Ladvise dontneed again failed"
21978         local no_read=$(facet_meminfo ost1 Cached)
21979         echo "Cache used after dontneed ladvise: $no_read KiB"
21980
21981         if [ $total -lt $((before_read + kibibytes)) ]; then
21982                 echo "Memory is too small, abort checking"
21983                 return 0
21984         fi
21985
21986         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21987                 error "Ladvise willread should use more memory" \
21988                         "than $kibibytes KiB"
21989         fi
21990
21991         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21992                 error "Ladvise dontneed should release more memory" \
21993                         "than $kibibytes KiB"
21994         fi
21995 }
21996 run_test 255b "check 'lfs ladvise -a dontneed'"
21997
21998 test_255c() {
21999         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22000                 skip "lustre < 2.10.50 does not support lockahead"
22001
22002         local ost1_imp=$(get_osc_import_name client ost1)
22003         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22004                          cut -d'.' -f2)
22005         local count
22006         local new_count
22007         local difference
22008         local i
22009         local rc
22010
22011         test_mkdir -p $DIR/$tdir
22012         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22013
22014         #test 10 returns only success/failure
22015         i=10
22016         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22017         rc=$?
22018         if [ $rc -eq 255 ]; then
22019                 error "Ladvise test${i} failed, ${rc}"
22020         fi
22021
22022         #test 11 counts lock enqueue requests, all others count new locks
22023         i=11
22024         count=$(do_facet ost1 \
22025                 $LCTL get_param -n ost.OSS.ost.stats)
22026         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22027
22028         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22029         rc=$?
22030         if [ $rc -eq 255 ]; then
22031                 error "Ladvise test${i} failed, ${rc}"
22032         fi
22033
22034         new_count=$(do_facet ost1 \
22035                 $LCTL get_param -n ost.OSS.ost.stats)
22036         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22037                    awk '{ print $2 }')
22038
22039         difference="$((new_count - count))"
22040         if [ $difference -ne $rc ]; then
22041                 error "Ladvise test${i}, bad enqueue count, returned " \
22042                       "${rc}, actual ${difference}"
22043         fi
22044
22045         for i in $(seq 12 21); do
22046                 # If we do not do this, we run the risk of having too many
22047                 # locks and starting lock cancellation while we are checking
22048                 # lock counts.
22049                 cancel_lru_locks osc
22050
22051                 count=$($LCTL get_param -n \
22052                        ldlm.namespaces.$imp_name.lock_unused_count)
22053
22054                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22055                 rc=$?
22056                 if [ $rc -eq 255 ]; then
22057                         error "Ladvise test ${i} failed, ${rc}"
22058                 fi
22059
22060                 new_count=$($LCTL get_param -n \
22061                        ldlm.namespaces.$imp_name.lock_unused_count)
22062                 difference="$((new_count - count))"
22063
22064                 # Test 15 output is divided by 100 to map down to valid return
22065                 if [ $i -eq 15 ]; then
22066                         rc="$((rc * 100))"
22067                 fi
22068
22069                 if [ $difference -ne $rc ]; then
22070                         error "Ladvise test ${i}, bad lock count, returned " \
22071                               "${rc}, actual ${difference}"
22072                 fi
22073         done
22074
22075         #test 22 returns only success/failure
22076         i=22
22077         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22078         rc=$?
22079         if [ $rc -eq 255 ]; then
22080                 error "Ladvise test${i} failed, ${rc}"
22081         fi
22082 }
22083 run_test 255c "suite of ladvise lockahead tests"
22084
22085 test_256() {
22086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22087         remote_mds_nodsh && skip "remote MDS with nodsh"
22088         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22089         changelog_users $SINGLEMDS | grep "^cl" &&
22090                 skip "active changelog user"
22091
22092         local cl_user
22093         local cat_sl
22094         local mdt_dev
22095
22096         mdt_dev=$(facet_device $SINGLEMDS)
22097         echo $mdt_dev
22098
22099         changelog_register || error "changelog_register failed"
22100
22101         rm -rf $DIR/$tdir
22102         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22103
22104         changelog_clear 0 || error "changelog_clear failed"
22105
22106         # change something
22107         touch $DIR/$tdir/{1..10}
22108
22109         # stop the MDT
22110         stop $SINGLEMDS || error "Fail to stop MDT"
22111
22112         # remount the MDT
22113         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22114                 error "Fail to start MDT"
22115
22116         #after mount new plainllog is used
22117         touch $DIR/$tdir/{11..19}
22118         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22119         stack_trap "rm -f $tmpfile"
22120         cat_sl=$(do_facet $SINGLEMDS "sync; \
22121                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22122                  llog_reader $tmpfile | grep -c type=1064553b")
22123         do_facet $SINGLEMDS llog_reader $tmpfile
22124
22125         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22126
22127         changelog_clear 0 || error "changelog_clear failed"
22128
22129         cat_sl=$(do_facet $SINGLEMDS "sync; \
22130                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22131                  llog_reader $tmpfile | grep -c type=1064553b")
22132
22133         if (( cat_sl == 2 )); then
22134                 error "Empty plain llog was not deleted from changelog catalog"
22135         elif (( cat_sl != 1 )); then
22136                 error "Active plain llog shouldn't be deleted from catalog"
22137         fi
22138 }
22139 run_test 256 "Check llog delete for empty and not full state"
22140
22141 test_257() {
22142         remote_mds_nodsh && skip "remote MDS with nodsh"
22143         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22144                 skip "Need MDS version at least 2.8.55"
22145
22146         test_mkdir $DIR/$tdir
22147
22148         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22149                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22150         stat $DIR/$tdir
22151
22152 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22153         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22154         local facet=mds$((mdtidx + 1))
22155         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22156         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22157
22158         stop $facet || error "stop MDS failed"
22159         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22160                 error "start MDS fail"
22161         wait_recovery_complete $facet
22162 }
22163 run_test 257 "xattr locks are not lost"
22164
22165 # Verify we take the i_mutex when security requires it
22166 test_258a() {
22167 #define OBD_FAIL_IMUTEX_SEC 0x141c
22168         $LCTL set_param fail_loc=0x141c
22169         touch $DIR/$tfile
22170         chmod u+s $DIR/$tfile
22171         chmod a+rwx $DIR/$tfile
22172         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22173         RC=$?
22174         if [ $RC -ne 0 ]; then
22175                 error "error, failed to take i_mutex, rc=$?"
22176         fi
22177         rm -f $DIR/$tfile
22178 }
22179 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22180
22181 # Verify we do NOT take the i_mutex in the normal case
22182 test_258b() {
22183 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22184         $LCTL set_param fail_loc=0x141d
22185         touch $DIR/$tfile
22186         chmod a+rwx $DIR
22187         chmod a+rw $DIR/$tfile
22188         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22189         RC=$?
22190         if [ $RC -ne 0 ]; then
22191                 error "error, took i_mutex unnecessarily, rc=$?"
22192         fi
22193         rm -f $DIR/$tfile
22194
22195 }
22196 run_test 258b "verify i_mutex security behavior"
22197
22198 test_259() {
22199         local file=$DIR/$tfile
22200         local before
22201         local after
22202
22203         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22204
22205         stack_trap "rm -f $file" EXIT
22206
22207         wait_delete_completed
22208         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22209         echo "before: $before"
22210
22211         $LFS setstripe -i 0 -c 1 $file
22212         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22213         sync_all_data
22214         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22215         echo "after write: $after"
22216
22217 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22218         do_facet ost1 $LCTL set_param fail_loc=0x2301
22219         $TRUNCATE $file 0
22220         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22221         echo "after truncate: $after"
22222
22223         stop ost1
22224         do_facet ost1 $LCTL set_param fail_loc=0
22225         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22226         sleep 2
22227         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22228         echo "after restart: $after"
22229         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22230                 error "missing truncate?"
22231
22232         return 0
22233 }
22234 run_test 259 "crash at delayed truncate"
22235
22236 test_260() {
22237 #define OBD_FAIL_MDC_CLOSE               0x806
22238         $LCTL set_param fail_loc=0x80000806
22239         touch $DIR/$tfile
22240
22241 }
22242 run_test 260 "Check mdc_close fail"
22243
22244 ### Data-on-MDT sanity tests ###
22245 test_270a() {
22246         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22247                 skip "Need MDS version at least 2.10.55 for DoM"
22248
22249         # create DoM file
22250         local dom=$DIR/$tdir/dom_file
22251         local tmp=$DIR/$tdir/tmp_file
22252
22253         mkdir_on_mdt0 $DIR/$tdir
22254
22255         # basic checks for DoM component creation
22256         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22257                 error "Can set MDT layout to non-first entry"
22258
22259         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22260                 error "Can define multiple entries as MDT layout"
22261
22262         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22263
22264         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22265         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22266         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22267
22268         local mdtidx=$($LFS getstripe -m $dom)
22269         local mdtname=MDT$(printf %04x $mdtidx)
22270         local facet=mds$((mdtidx + 1))
22271         local space_check=1
22272
22273         # Skip free space checks with ZFS
22274         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22275
22276         # write
22277         sync
22278         local size_tmp=$((65536 * 3))
22279         local mdtfree1=$(do_facet $facet \
22280                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22281
22282         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22283         # check also direct IO along write
22284         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22285         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22286         sync
22287         cmp $tmp $dom || error "file data is different"
22288         [ $(stat -c%s $dom) == $size_tmp ] ||
22289                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22290         if [ $space_check == 1 ]; then
22291                 local mdtfree2=$(do_facet $facet \
22292                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22293
22294                 # increase in usage from by $size_tmp
22295                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22296                         error "MDT free space wrong after write: " \
22297                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22298         fi
22299
22300         # truncate
22301         local size_dom=10000
22302
22303         $TRUNCATE $dom $size_dom
22304         [ $(stat -c%s $dom) == $size_dom ] ||
22305                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22306         if [ $space_check == 1 ]; then
22307                 mdtfree1=$(do_facet $facet \
22308                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22309                 # decrease in usage from $size_tmp to new $size_dom
22310                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22311                   $(((size_tmp - size_dom) / 1024)) ] ||
22312                         error "MDT free space is wrong after truncate: " \
22313                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22314         fi
22315
22316         # append
22317         cat $tmp >> $dom
22318         sync
22319         size_dom=$((size_dom + size_tmp))
22320         [ $(stat -c%s $dom) == $size_dom ] ||
22321                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22322         if [ $space_check == 1 ]; then
22323                 mdtfree2=$(do_facet $facet \
22324                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22325                 # increase in usage by $size_tmp from previous
22326                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22327                         error "MDT free space is wrong after append: " \
22328                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22329         fi
22330
22331         # delete
22332         rm $dom
22333         if [ $space_check == 1 ]; then
22334                 mdtfree1=$(do_facet $facet \
22335                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22336                 # decrease in usage by $size_dom from previous
22337                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22338                         error "MDT free space is wrong after removal: " \
22339                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22340         fi
22341
22342         # combined striping
22343         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22344                 error "Can't create DoM + OST striping"
22345
22346         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22347         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22348         # check also direct IO along write
22349         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22350         sync
22351         cmp $tmp $dom || error "file data is different"
22352         [ $(stat -c%s $dom) == $size_tmp ] ||
22353                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22354         rm $dom $tmp
22355
22356         return 0
22357 }
22358 run_test 270a "DoM: basic functionality tests"
22359
22360 test_270b() {
22361         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22362                 skip "Need MDS version at least 2.10.55"
22363
22364         local dom=$DIR/$tdir/dom_file
22365         local max_size=1048576
22366
22367         mkdir -p $DIR/$tdir
22368         $LFS setstripe -E $max_size -L mdt $dom
22369
22370         # truncate over the limit
22371         $TRUNCATE $dom $(($max_size + 1)) &&
22372                 error "successful truncate over the maximum size"
22373         # write over the limit
22374         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22375                 error "successful write over the maximum size"
22376         # append over the limit
22377         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22378         echo "12345" >> $dom && error "successful append over the maximum size"
22379         rm $dom
22380
22381         return 0
22382 }
22383 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22384
22385 test_270c() {
22386         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22387                 skip "Need MDS version at least 2.10.55"
22388
22389         mkdir -p $DIR/$tdir
22390         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22391
22392         # check files inherit DoM EA
22393         touch $DIR/$tdir/first
22394         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22395                 error "bad pattern"
22396         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22397                 error "bad stripe count"
22398         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22399                 error "bad stripe size"
22400
22401         # check directory inherits DoM EA and uses it as default
22402         mkdir $DIR/$tdir/subdir
22403         touch $DIR/$tdir/subdir/second
22404         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22405                 error "bad pattern in sub-directory"
22406         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22407                 error "bad stripe count in sub-directory"
22408         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22409                 error "bad stripe size in sub-directory"
22410         return 0
22411 }
22412 run_test 270c "DoM: DoM EA inheritance tests"
22413
22414 test_270d() {
22415         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22416                 skip "Need MDS version at least 2.10.55"
22417
22418         mkdir -p $DIR/$tdir
22419         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22420
22421         # inherit default DoM striping
22422         mkdir $DIR/$tdir/subdir
22423         touch $DIR/$tdir/subdir/f1
22424
22425         # change default directory striping
22426         $LFS setstripe -c 1 $DIR/$tdir/subdir
22427         touch $DIR/$tdir/subdir/f2
22428         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22429                 error "wrong default striping in file 2"
22430         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22431                 error "bad pattern in file 2"
22432         return 0
22433 }
22434 run_test 270d "DoM: change striping from DoM to RAID0"
22435
22436 test_270e() {
22437         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22438                 skip "Need MDS version at least 2.10.55"
22439
22440         mkdir -p $DIR/$tdir/dom
22441         mkdir -p $DIR/$tdir/norm
22442         DOMFILES=20
22443         NORMFILES=10
22444         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22445         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22446
22447         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22448         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22449
22450         # find DoM files by layout
22451         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22452         [ $NUM -eq  $DOMFILES ] ||
22453                 error "lfs find -L: found $NUM, expected $DOMFILES"
22454         echo "Test 1: lfs find 20 DOM files by layout: OK"
22455
22456         # there should be 1 dir with default DOM striping
22457         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22458         [ $NUM -eq  1 ] ||
22459                 error "lfs find -L: found $NUM, expected 1 dir"
22460         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22461
22462         # find DoM files by stripe size
22463         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22464         [ $NUM -eq  $DOMFILES ] ||
22465                 error "lfs find -S: found $NUM, expected $DOMFILES"
22466         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22467
22468         # find files by stripe offset except DoM files
22469         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22470         [ $NUM -eq  $NORMFILES ] ||
22471                 error "lfs find -i: found $NUM, expected $NORMFILES"
22472         echo "Test 5: lfs find no DOM files by stripe index: OK"
22473         return 0
22474 }
22475 run_test 270e "DoM: lfs find with DoM files test"
22476
22477 test_270f() {
22478         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22479                 skip "Need MDS version at least 2.10.55"
22480
22481         local mdtname=${FSNAME}-MDT0000-mdtlov
22482         local dom=$DIR/$tdir/dom_file
22483         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22484                                                 lod.$mdtname.dom_stripesize)
22485         local dom_limit=131072
22486
22487         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22488         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22489                                                 lod.$mdtname.dom_stripesize)
22490         [ ${dom_limit} -eq ${dom_current} ] ||
22491                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22492
22493         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22494         $LFS setstripe -d $DIR/$tdir
22495         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22496                 error "Can't set directory default striping"
22497
22498         # exceed maximum stripe size
22499         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22500                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22501         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22502                 error "Able to create DoM component size more than LOD limit"
22503
22504         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22505         dom_current=$(do_facet mds1 $LCTL get_param -n \
22506                                                 lod.$mdtname.dom_stripesize)
22507         [ 0 -eq ${dom_current} ] ||
22508                 error "Can't set zero DoM stripe limit"
22509         rm $dom
22510
22511         # attempt to create DoM file on server with disabled DoM should
22512         # remove DoM entry from layout and be succeed
22513         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22514                 error "Can't create DoM file (DoM is disabled)"
22515         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22516                 error "File has DoM component while DoM is disabled"
22517         rm $dom
22518
22519         # attempt to create DoM file with only DoM stripe should return error
22520         $LFS setstripe -E $dom_limit -L mdt $dom &&
22521                 error "Able to create DoM-only file while DoM is disabled"
22522
22523         # too low values to be aligned with smallest stripe size 64K
22524         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22525         dom_current=$(do_facet mds1 $LCTL get_param -n \
22526                                                 lod.$mdtname.dom_stripesize)
22527         [ 30000 -eq ${dom_current} ] &&
22528                 error "Can set too small DoM stripe limit"
22529
22530         # 64K is a minimal stripe size in Lustre, expect limit of that size
22531         [ 65536 -eq ${dom_current} ] ||
22532                 error "Limit is not set to 64K but ${dom_current}"
22533
22534         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22535         dom_current=$(do_facet mds1 $LCTL get_param -n \
22536                                                 lod.$mdtname.dom_stripesize)
22537         echo $dom_current
22538         [ 2147483648 -eq ${dom_current} ] &&
22539                 error "Can set too large DoM stripe limit"
22540
22541         do_facet mds1 $LCTL set_param -n \
22542                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22543         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22544                 error "Can't create DoM component size after limit change"
22545         do_facet mds1 $LCTL set_param -n \
22546                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22547         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22548                 error "Can't create DoM file after limit decrease"
22549         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22550                 error "Can create big DoM component after limit decrease"
22551         touch ${dom}_def ||
22552                 error "Can't create file with old default layout"
22553
22554         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22555         return 0
22556 }
22557 run_test 270f "DoM: maximum DoM stripe size checks"
22558
22559 test_270g() {
22560         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22561                 skip "Need MDS version at least 2.13.52"
22562         local dom=$DIR/$tdir/$tfile
22563
22564         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22565         local lodname=${FSNAME}-MDT0000-mdtlov
22566
22567         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22568         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22569         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22570         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22571
22572         local dom_limit=1024
22573         local dom_threshold="50%"
22574
22575         $LFS setstripe -d $DIR/$tdir
22576         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22577                 error "Can't set directory default striping"
22578
22579         do_facet mds1 $LCTL set_param -n \
22580                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22581         # set 0 threshold and create DOM file to change tunable stripesize
22582         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22583         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22584                 error "Failed to create $dom file"
22585         # now tunable dom_cur_stripesize should reach maximum
22586         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22587                                         lod.${lodname}.dom_stripesize_cur_kb)
22588         [[ $dom_current == $dom_limit ]] ||
22589                 error "Current DOM stripesize is not maximum"
22590         rm $dom
22591
22592         # set threshold for further tests
22593         do_facet mds1 $LCTL set_param -n \
22594                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22595         echo "DOM threshold is $dom_threshold free space"
22596         local dom_def
22597         local dom_set
22598         # Spoof bfree to exceed threshold
22599         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22600         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22601         for spfree in 40 20 0 15 30 55; do
22602                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22603                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22604                         error "Failed to create $dom file"
22605                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22606                                         lod.${lodname}.dom_stripesize_cur_kb)
22607                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22608                 [[ $dom_def != $dom_current ]] ||
22609                         error "Default stripe size was not changed"
22610                 if (( spfree > 0 )) ; then
22611                         dom_set=$($LFS getstripe -S $dom)
22612                         (( dom_set == dom_def * 1024 )) ||
22613                                 error "DOM component size is still old"
22614                 else
22615                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22616                                 error "DoM component is set with no free space"
22617                 fi
22618                 rm $dom
22619                 dom_current=$dom_def
22620         done
22621 }
22622 run_test 270g "DoM: default DoM stripe size depends on free space"
22623
22624 test_270h() {
22625         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22626                 skip "Need MDS version at least 2.13.53"
22627
22628         local mdtname=${FSNAME}-MDT0000-mdtlov
22629         local dom=$DIR/$tdir/$tfile
22630         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22631
22632         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22633         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22634
22635         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22636         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22637                 error "can't create OST file"
22638         # mirrored file with DOM entry in the second mirror
22639         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22640                 error "can't create mirror with DoM component"
22641
22642         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22643
22644         # DOM component in the middle and has other enries in the same mirror,
22645         # should succeed but lost DoM component
22646         $LFS setstripe --copy=${dom}_1 $dom ||
22647                 error "Can't create file from OST|DOM mirror layout"
22648         # check new file has no DoM layout after all
22649         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22650                 error "File has DoM component while DoM is disabled"
22651 }
22652 run_test 270h "DoM: DoM stripe removal when disabled on server"
22653
22654 test_270i() {
22655         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22656                 skip "Need MDS version at least 2.14.54"
22657
22658         mkdir $DIR/$tdir
22659         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22660                 error "setstripe should fail" || true
22661 }
22662 run_test 270i "DoM: setting invalid DoM striping should fail"
22663
22664 test_271a() {
22665         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22666                 skip "Need MDS version at least 2.10.55"
22667
22668         local dom=$DIR/$tdir/dom
22669
22670         mkdir -p $DIR/$tdir
22671
22672         $LFS setstripe -E 1024K -L mdt $dom
22673
22674         lctl set_param -n mdc.*.stats=clear
22675         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22676         cat $dom > /dev/null
22677         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22678         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22679         ls $dom
22680         rm -f $dom
22681 }
22682 run_test 271a "DoM: data is cached for read after write"
22683
22684 test_271b() {
22685         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22686                 skip "Need MDS version at least 2.10.55"
22687
22688         local dom=$DIR/$tdir/dom
22689
22690         mkdir -p $DIR/$tdir
22691
22692         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22693
22694         lctl set_param -n mdc.*.stats=clear
22695         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22696         cancel_lru_locks mdc
22697         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22698         # second stat to check size is cached on client
22699         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22700         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22701         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22702         rm -f $dom
22703 }
22704 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22705
22706 test_271ba() {
22707         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22708                 skip "Need MDS version at least 2.10.55"
22709
22710         local dom=$DIR/$tdir/dom
22711
22712         mkdir -p $DIR/$tdir
22713
22714         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22715
22716         lctl set_param -n mdc.*.stats=clear
22717         lctl set_param -n osc.*.stats=clear
22718         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22719         cancel_lru_locks mdc
22720         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22721         # second stat to check size is cached on client
22722         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22723         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22724         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22725         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22726         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22727         rm -f $dom
22728 }
22729 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22730
22731
22732 get_mdc_stats() {
22733         local mdtidx=$1
22734         local param=$2
22735         local mdt=MDT$(printf %04x $mdtidx)
22736
22737         if [ -z $param ]; then
22738                 lctl get_param -n mdc.*$mdt*.stats
22739         else
22740                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22741         fi
22742 }
22743
22744 test_271c() {
22745         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22746                 skip "Need MDS version at least 2.10.55"
22747
22748         local dom=$DIR/$tdir/dom
22749
22750         mkdir -p $DIR/$tdir
22751
22752         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22753
22754         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22755         local facet=mds$((mdtidx + 1))
22756
22757         cancel_lru_locks mdc
22758         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22759         createmany -o $dom 1000
22760         lctl set_param -n mdc.*.stats=clear
22761         smalliomany -w $dom 1000 200
22762         get_mdc_stats $mdtidx
22763         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22764         # Each file has 1 open, 1 IO enqueues, total 2000
22765         # but now we have also +1 getxattr for security.capability, total 3000
22766         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22767         unlinkmany $dom 1000
22768
22769         cancel_lru_locks mdc
22770         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22771         createmany -o $dom 1000
22772         lctl set_param -n mdc.*.stats=clear
22773         smalliomany -w $dom 1000 200
22774         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22775         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22776         # for OPEN and IO lock.
22777         [ $((enq - enq_2)) -ge 1000 ] ||
22778                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22779         unlinkmany $dom 1000
22780         return 0
22781 }
22782 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22783
22784 cleanup_271def_tests() {
22785         trap 0
22786         rm -f $1
22787 }
22788
22789 test_271d() {
22790         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22791                 skip "Need MDS version at least 2.10.57"
22792
22793         local dom=$DIR/$tdir/dom
22794         local tmp=$TMP/$tfile
22795         trap "cleanup_271def_tests $tmp" EXIT
22796
22797         mkdir -p $DIR/$tdir
22798
22799         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22800
22801         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22802
22803         cancel_lru_locks mdc
22804         dd if=/dev/urandom of=$tmp bs=1000 count=1
22805         dd if=$tmp of=$dom bs=1000 count=1
22806         cancel_lru_locks mdc
22807
22808         cat /etc/hosts >> $tmp
22809         lctl set_param -n mdc.*.stats=clear
22810
22811         # append data to the same file it should update local page
22812         echo "Append to the same page"
22813         cat /etc/hosts >> $dom
22814         local num=$(get_mdc_stats $mdtidx ost_read)
22815         local ra=$(get_mdc_stats $mdtidx req_active)
22816         local rw=$(get_mdc_stats $mdtidx req_waittime)
22817
22818         [ -z $num ] || error "$num READ RPC occured"
22819         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22820         echo "... DONE"
22821
22822         # compare content
22823         cmp $tmp $dom || error "file miscompare"
22824
22825         cancel_lru_locks mdc
22826         lctl set_param -n mdc.*.stats=clear
22827
22828         echo "Open and read file"
22829         cat $dom > /dev/null
22830         local num=$(get_mdc_stats $mdtidx ost_read)
22831         local ra=$(get_mdc_stats $mdtidx req_active)
22832         local rw=$(get_mdc_stats $mdtidx req_waittime)
22833
22834         [ -z $num ] || error "$num READ RPC occured"
22835         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22836         echo "... DONE"
22837
22838         # compare content
22839         cmp $tmp $dom || error "file miscompare"
22840
22841         return 0
22842 }
22843 run_test 271d "DoM: read on open (1K file in reply buffer)"
22844
22845 test_271f() {
22846         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22847                 skip "Need MDS version at least 2.10.57"
22848
22849         local dom=$DIR/$tdir/dom
22850         local tmp=$TMP/$tfile
22851         trap "cleanup_271def_tests $tmp" EXIT
22852
22853         mkdir -p $DIR/$tdir
22854
22855         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22856
22857         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22858
22859         cancel_lru_locks mdc
22860         dd if=/dev/urandom of=$tmp bs=265000 count=1
22861         dd if=$tmp of=$dom bs=265000 count=1
22862         cancel_lru_locks mdc
22863         cat /etc/hosts >> $tmp
22864         lctl set_param -n mdc.*.stats=clear
22865
22866         echo "Append to the same page"
22867         cat /etc/hosts >> $dom
22868         local num=$(get_mdc_stats $mdtidx ost_read)
22869         local ra=$(get_mdc_stats $mdtidx req_active)
22870         local rw=$(get_mdc_stats $mdtidx req_waittime)
22871
22872         [ -z $num ] || error "$num READ RPC occured"
22873         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22874         echo "... DONE"
22875
22876         # compare content
22877         cmp $tmp $dom || error "file miscompare"
22878
22879         cancel_lru_locks mdc
22880         lctl set_param -n mdc.*.stats=clear
22881
22882         echo "Open and read file"
22883         cat $dom > /dev/null
22884         local num=$(get_mdc_stats $mdtidx ost_read)
22885         local ra=$(get_mdc_stats $mdtidx req_active)
22886         local rw=$(get_mdc_stats $mdtidx req_waittime)
22887
22888         [ -z $num ] && num=0
22889         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22890         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22891         echo "... DONE"
22892
22893         # compare content
22894         cmp $tmp $dom || error "file miscompare"
22895
22896         return 0
22897 }
22898 run_test 271f "DoM: read on open (200K file and read tail)"
22899
22900 test_271g() {
22901         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22902                 skip "Skipping due to old client or server version"
22903
22904         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22905         # to get layout
22906         $CHECKSTAT -t file $DIR1/$tfile
22907
22908         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22909         MULTIOP_PID=$!
22910         sleep 1
22911         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22912         $LCTL set_param fail_loc=0x80000314
22913         rm $DIR1/$tfile || error "Unlink fails"
22914         RC=$?
22915         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22916         [ $RC -eq 0 ] || error "Failed write to stale object"
22917 }
22918 run_test 271g "Discard DoM data vs client flush race"
22919
22920 test_272a() {
22921         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22922                 skip "Need MDS version at least 2.11.50"
22923
22924         local dom=$DIR/$tdir/dom
22925         mkdir -p $DIR/$tdir
22926
22927         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22928         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22929                 error "failed to write data into $dom"
22930         local old_md5=$(md5sum $dom)
22931
22932         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22933                 error "failed to migrate to the same DoM component"
22934
22935         local new_md5=$(md5sum $dom)
22936
22937         [ "$old_md5" == "$new_md5" ] ||
22938                 error "md5sum differ: $old_md5, $new_md5"
22939
22940         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22941                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22942 }
22943 run_test 272a "DoM migration: new layout with the same DOM component"
22944
22945 test_272b() {
22946         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22947                 skip "Need MDS version at least 2.11.50"
22948
22949         local dom=$DIR/$tdir/dom
22950         mkdir -p $DIR/$tdir
22951         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22952
22953         local mdtidx=$($LFS getstripe -m $dom)
22954         local mdtname=MDT$(printf %04x $mdtidx)
22955         local facet=mds$((mdtidx + 1))
22956
22957         local mdtfree1=$(do_facet $facet \
22958                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22959         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22960                 error "failed to write data into $dom"
22961         local old_md5=$(md5sum $dom)
22962         cancel_lru_locks mdc
22963         local mdtfree1=$(do_facet $facet \
22964                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22965
22966         $LFS migrate -c2 $dom ||
22967                 error "failed to migrate to the new composite layout"
22968         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22969                 error "MDT stripe was not removed"
22970
22971         cancel_lru_locks mdc
22972         local new_md5=$(md5sum $dom)
22973         [ "$old_md5" == "$new_md5" ] ||
22974                 error "$old_md5 != $new_md5"
22975
22976         # Skip free space checks with ZFS
22977         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22978                 local mdtfree2=$(do_facet $facet \
22979                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22980                 [ $mdtfree2 -gt $mdtfree1 ] ||
22981                         error "MDT space is not freed after migration"
22982         fi
22983         return 0
22984 }
22985 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22986
22987 test_272c() {
22988         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22989                 skip "Need MDS version at least 2.11.50"
22990
22991         local dom=$DIR/$tdir/$tfile
22992         mkdir -p $DIR/$tdir
22993         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22994
22995         local mdtidx=$($LFS getstripe -m $dom)
22996         local mdtname=MDT$(printf %04x $mdtidx)
22997         local facet=mds$((mdtidx + 1))
22998
22999         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23000                 error "failed to write data into $dom"
23001         local old_md5=$(md5sum $dom)
23002         cancel_lru_locks mdc
23003         local mdtfree1=$(do_facet $facet \
23004                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23005
23006         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23007                 error "failed to migrate to the new composite layout"
23008         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23009                 error "MDT stripe was not removed"
23010
23011         cancel_lru_locks mdc
23012         local new_md5=$(md5sum $dom)
23013         [ "$old_md5" == "$new_md5" ] ||
23014                 error "$old_md5 != $new_md5"
23015
23016         # Skip free space checks with ZFS
23017         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23018                 local mdtfree2=$(do_facet $facet \
23019                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23020                 [ $mdtfree2 -gt $mdtfree1 ] ||
23021                         error "MDS space is not freed after migration"
23022         fi
23023         return 0
23024 }
23025 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23026
23027 test_272d() {
23028         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23029                 skip "Need MDS version at least 2.12.55"
23030
23031         local dom=$DIR/$tdir/$tfile
23032         mkdir -p $DIR/$tdir
23033         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23034
23035         local mdtidx=$($LFS getstripe -m $dom)
23036         local mdtname=MDT$(printf %04x $mdtidx)
23037         local facet=mds$((mdtidx + 1))
23038
23039         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23040                 error "failed to write data into $dom"
23041         local old_md5=$(md5sum $dom)
23042         cancel_lru_locks mdc
23043         local mdtfree1=$(do_facet $facet \
23044                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23045
23046         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23047                 error "failed mirroring to the new composite layout"
23048         $LFS mirror resync $dom ||
23049                 error "failed mirror resync"
23050         $LFS mirror split --mirror-id 1 -d $dom ||
23051                 error "failed mirror split"
23052
23053         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23054                 error "MDT stripe was not removed"
23055
23056         cancel_lru_locks mdc
23057         local new_md5=$(md5sum $dom)
23058         [ "$old_md5" == "$new_md5" ] ||
23059                 error "$old_md5 != $new_md5"
23060
23061         # Skip free space checks with ZFS
23062         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23063                 local mdtfree2=$(do_facet $facet \
23064                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23065                 [ $mdtfree2 -gt $mdtfree1 ] ||
23066                         error "MDS space is not freed after DOM mirror deletion"
23067         fi
23068         return 0
23069 }
23070 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23071
23072 test_272e() {
23073         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23074                 skip "Need MDS version at least 2.12.55"
23075
23076         local dom=$DIR/$tdir/$tfile
23077         mkdir -p $DIR/$tdir
23078         $LFS setstripe -c 2 $dom
23079
23080         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23081                 error "failed to write data into $dom"
23082         local old_md5=$(md5sum $dom)
23083         cancel_lru_locks
23084
23085         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23086                 error "failed mirroring to the DOM layout"
23087         $LFS mirror resync $dom ||
23088                 error "failed mirror resync"
23089         $LFS mirror split --mirror-id 1 -d $dom ||
23090                 error "failed mirror split"
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 272e "DoM mirroring: DOM mirror to the OST-striped file"
23103
23104 test_272f() {
23105         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23106                 skip "Need MDS version at least 2.12.55"
23107
23108         local dom=$DIR/$tdir/$tfile
23109         mkdir -p $DIR/$tdir
23110         $LFS setstripe -c 2 $dom
23111
23112         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23113                 error "failed to write data into $dom"
23114         local old_md5=$(md5sum $dom)
23115         cancel_lru_locks
23116
23117         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23118                 error "failed migrating to the DOM file"
23119
23120         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23121                 error "MDT stripe wasn't set"
23122
23123         cancel_lru_locks
23124         local new_md5=$(md5sum $dom)
23125         [ "$old_md5" != "$new_md5" ] &&
23126                 error "$old_md5 != $new_md5"
23127
23128         return 0
23129 }
23130 run_test 272f "DoM migration: OST-striped file to DOM file"
23131
23132 test_273a() {
23133         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23134                 skip "Need MDS version at least 2.11.50"
23135
23136         # Layout swap cannot be done if either file has DOM component,
23137         # this will never be supported, migration should be used instead
23138
23139         local dom=$DIR/$tdir/$tfile
23140         mkdir -p $DIR/$tdir
23141
23142         $LFS setstripe -c2 ${dom}_plain
23143         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23144         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23145                 error "can swap layout with DoM component"
23146         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23147                 error "can swap layout with DoM component"
23148
23149         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23150         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23151                 error "can swap layout with DoM component"
23152         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23153                 error "can swap layout with DoM component"
23154         return 0
23155 }
23156 run_test 273a "DoM: layout swapping should fail with DOM"
23157
23158 test_273b() {
23159         mkdir -p $DIR/$tdir
23160         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23161
23162 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23163         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23164
23165         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23166 }
23167 run_test 273b "DoM: race writeback and object destroy"
23168
23169 test_275() {
23170         remote_ost_nodsh && skip "remote OST with nodsh"
23171         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23172                 skip "Need OST version >= 2.10.57"
23173
23174         local file=$DIR/$tfile
23175         local oss
23176
23177         oss=$(comma_list $(osts_nodes))
23178
23179         dd if=/dev/urandom of=$file bs=1M count=2 ||
23180                 error "failed to create a file"
23181         cancel_lru_locks osc
23182
23183         #lock 1
23184         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23185                 error "failed to read a file"
23186
23187 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23188         $LCTL set_param fail_loc=0x8000031f
23189
23190         cancel_lru_locks osc &
23191         sleep 1
23192
23193 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23194         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23195         #IO takes another lock, but matches the PENDING one
23196         #and places it to the IO RPC
23197         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23198                 error "failed to read a file with PENDING lock"
23199 }
23200 run_test 275 "Read on a canceled duplicate lock"
23201
23202 test_276() {
23203         remote_ost_nodsh && skip "remote OST with nodsh"
23204         local pid
23205
23206         do_facet ost1 "(while true; do \
23207                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23208                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23209         pid=$!
23210
23211         for LOOP in $(seq 20); do
23212                 stop ost1
23213                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23214         done
23215         kill -9 $pid
23216         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23217                 rm $TMP/sanity_276_pid"
23218 }
23219 run_test 276 "Race between mount and obd_statfs"
23220
23221 test_277() {
23222         $LCTL set_param ldlm.namespaces.*.lru_size=0
23223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23224         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23225                         grep ^used_mb | awk '{print $2}')
23226         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23228                 oflag=direct conv=notrunc
23229         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23230                         grep ^used_mb | awk '{print $2}')
23231         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23232 }
23233 run_test 277 "Direct IO shall drop page cache"
23234
23235 test_278() {
23236         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23238         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23239                 skip "needs the same host for mdt1 mdt2" && return
23240
23241         local pid1
23242         local pid2
23243
23244 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23245         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23246         stop mds2 &
23247         pid2=$!
23248
23249         stop mds1
23250
23251         echo "Starting MDTs"
23252         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23253         wait $pid2
23254 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23255 #will return NULL
23256         do_facet mds2 $LCTL set_param fail_loc=0
23257
23258         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23259         wait_recovery_complete mds2
23260 }
23261 run_test 278 "Race starting MDS between MDTs stop/start"
23262
23263 test_280() {
23264         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23265                 skip "Need MGS version at least 2.13.52"
23266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23267         combined_mgs_mds || skip "needs combined MGS/MDT"
23268
23269         umount_client $MOUNT
23270 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23271         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23272
23273         mount_client $MOUNT &
23274         sleep 1
23275         stop mgs || error "stop mgs failed"
23276         #for a race mgs would crash
23277         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23278         # make sure we unmount client before remounting
23279         wait
23280         umount_client $MOUNT
23281         mount_client $MOUNT || error "mount client failed"
23282 }
23283 run_test 280 "Race between MGS umount and client llog processing"
23284
23285 cleanup_test_300() {
23286         trap 0
23287         umask $SAVE_UMASK
23288 }
23289 test_striped_dir() {
23290         local mdt_index=$1
23291         local stripe_count
23292         local stripe_index
23293
23294         mkdir -p $DIR/$tdir
23295
23296         SAVE_UMASK=$(umask)
23297         trap cleanup_test_300 RETURN EXIT
23298
23299         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23300                                                 $DIR/$tdir/striped_dir ||
23301                 error "set striped dir error"
23302
23303         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23304         [ "$mode" = "755" ] || error "expect 755 got $mode"
23305
23306         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23307                 error "getdirstripe failed"
23308         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23309         if [ "$stripe_count" != "2" ]; then
23310                 error "1:stripe_count is $stripe_count, expect 2"
23311         fi
23312         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23313         if [ "$stripe_count" != "2" ]; then
23314                 error "2:stripe_count is $stripe_count, expect 2"
23315         fi
23316
23317         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23318         if [ "$stripe_index" != "$mdt_index" ]; then
23319                 error "stripe_index is $stripe_index, expect $mdt_index"
23320         fi
23321
23322         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23323                 error "nlink error after create striped dir"
23324
23325         mkdir $DIR/$tdir/striped_dir/a
23326         mkdir $DIR/$tdir/striped_dir/b
23327
23328         stat $DIR/$tdir/striped_dir/a ||
23329                 error "create dir under striped dir failed"
23330         stat $DIR/$tdir/striped_dir/b ||
23331                 error "create dir under striped dir failed"
23332
23333         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23334                 error "nlink error after mkdir"
23335
23336         rmdir $DIR/$tdir/striped_dir/a
23337         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23338                 error "nlink error after rmdir"
23339
23340         rmdir $DIR/$tdir/striped_dir/b
23341         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23342                 error "nlink error after rmdir"
23343
23344         chattr +i $DIR/$tdir/striped_dir
23345         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23346                 error "immutable flags not working under striped dir!"
23347         chattr -i $DIR/$tdir/striped_dir
23348
23349         rmdir $DIR/$tdir/striped_dir ||
23350                 error "rmdir striped dir error"
23351
23352         cleanup_test_300
23353
23354         true
23355 }
23356
23357 test_300a() {
23358         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23359                 skip "skipped for lustre < 2.7.0"
23360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23362
23363         test_striped_dir 0 || error "failed on striped dir on MDT0"
23364         test_striped_dir 1 || error "failed on striped dir on MDT0"
23365 }
23366 run_test 300a "basic striped dir sanity test"
23367
23368 test_300b() {
23369         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23370                 skip "skipped for lustre < 2.7.0"
23371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23373
23374         local i
23375         local mtime1
23376         local mtime2
23377         local mtime3
23378
23379         test_mkdir $DIR/$tdir || error "mkdir fail"
23380         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23381                 error "set striped dir error"
23382         for i in {0..9}; do
23383                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23384                 sleep 1
23385                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23386                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23387                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23388                 sleep 1
23389                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23390                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23391                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23392         done
23393         true
23394 }
23395 run_test 300b "check ctime/mtime for striped dir"
23396
23397 test_300c() {
23398         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23399                 skip "skipped for lustre < 2.7.0"
23400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23402
23403         local file_count
23404
23405         mkdir_on_mdt0 $DIR/$tdir
23406         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23407                 error "set striped dir error"
23408
23409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23410                 error "chown striped dir failed"
23411
23412         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23413                 error "create 5k files failed"
23414
23415         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23416
23417         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23418
23419         rm -rf $DIR/$tdir
23420 }
23421 run_test 300c "chown && check ls under striped directory"
23422
23423 test_300d() {
23424         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23425                 skip "skipped for lustre < 2.7.0"
23426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23428
23429         local stripe_count
23430         local file
23431
23432         mkdir -p $DIR/$tdir
23433         $LFS setstripe -c 2 $DIR/$tdir
23434
23435         #local striped directory
23436         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23437                 error "set striped dir error"
23438         #look at the directories for debug purposes
23439         ls -l $DIR/$tdir
23440         $LFS getdirstripe $DIR/$tdir
23441         ls -l $DIR/$tdir/striped_dir
23442         $LFS getdirstripe $DIR/$tdir/striped_dir
23443         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23444                 error "create 10 files failed"
23445
23446         #remote striped directory
23447         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23448                 error "set striped dir error"
23449         #look at the directories for debug purposes
23450         ls -l $DIR/$tdir
23451         $LFS getdirstripe $DIR/$tdir
23452         ls -l $DIR/$tdir/remote_striped_dir
23453         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23454         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23455                 error "create 10 files failed"
23456
23457         for file in $(find $DIR/$tdir); do
23458                 stripe_count=$($LFS getstripe -c $file)
23459                 [ $stripe_count -eq 2 ] ||
23460                         error "wrong stripe $stripe_count for $file"
23461         done
23462
23463         rm -rf $DIR/$tdir
23464 }
23465 run_test 300d "check default stripe under striped directory"
23466
23467 test_300e() {
23468         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23469                 skip "Need MDS version at least 2.7.55"
23470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23472
23473         local stripe_count
23474         local file
23475
23476         mkdir -p $DIR/$tdir
23477
23478         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23479                 error "set striped dir error"
23480
23481         touch $DIR/$tdir/striped_dir/a
23482         touch $DIR/$tdir/striped_dir/b
23483         touch $DIR/$tdir/striped_dir/c
23484
23485         mkdir $DIR/$tdir/striped_dir/dir_a
23486         mkdir $DIR/$tdir/striped_dir/dir_b
23487         mkdir $DIR/$tdir/striped_dir/dir_c
23488
23489         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23490                 error "set striped adir under striped dir error"
23491
23492         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23493                 error "set striped bdir under striped dir error"
23494
23495         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23496                 error "set striped cdir under striped dir error"
23497
23498         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23499                 error "rename dir under striped dir fails"
23500
23501         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23502                 error "rename dir under different stripes fails"
23503
23504         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23505                 error "rename file under striped dir should succeed"
23506
23507         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23508                 error "rename dir under striped dir should succeed"
23509
23510         rm -rf $DIR/$tdir
23511 }
23512 run_test 300e "check rename under striped directory"
23513
23514 test_300f() {
23515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23516         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23517         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23518                 skip "Need MDS version at least 2.7.55"
23519
23520         local stripe_count
23521         local file
23522
23523         rm -rf $DIR/$tdir
23524         mkdir -p $DIR/$tdir
23525
23526         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23527                 error "set striped dir error"
23528
23529         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23530                 error "set striped dir error"
23531
23532         touch $DIR/$tdir/striped_dir/a
23533         mkdir $DIR/$tdir/striped_dir/dir_a
23534         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23535                 error "create striped dir under striped dir fails"
23536
23537         touch $DIR/$tdir/striped_dir1/b
23538         mkdir $DIR/$tdir/striped_dir1/dir_b
23539         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23540                 error "create striped dir under striped dir fails"
23541
23542         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23543                 error "rename dir under different striped dir should fail"
23544
23545         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23546                 error "rename striped dir under diff striped dir should fail"
23547
23548         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23549                 error "rename file under diff striped dirs fails"
23550
23551         rm -rf $DIR/$tdir
23552 }
23553 run_test 300f "check rename cross striped directory"
23554
23555 test_300_check_default_striped_dir()
23556 {
23557         local dirname=$1
23558         local default_count=$2
23559         local default_index=$3
23560         local stripe_count
23561         local stripe_index
23562         local dir_stripe_index
23563         local dir
23564
23565         echo "checking $dirname $default_count $default_index"
23566         $LFS setdirstripe -D -c $default_count -i $default_index \
23567                                 -H all_char $DIR/$tdir/$dirname ||
23568                 error "set default stripe on striped dir error"
23569         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23570         [ $stripe_count -eq $default_count ] ||
23571                 error "expect $default_count get $stripe_count for $dirname"
23572
23573         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23574         [ $stripe_index -eq $default_index ] ||
23575                 error "expect $default_index get $stripe_index for $dirname"
23576
23577         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23578                                                 error "create dirs failed"
23579
23580         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23581         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23582         for dir in $(find $DIR/$tdir/$dirname/*); do
23583                 stripe_count=$($LFS getdirstripe -c $dir)
23584                 (( $stripe_count == $default_count )) ||
23585                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23586                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23587                 error "stripe count $default_count != $stripe_count for $dir"
23588
23589                 stripe_index=$($LFS getdirstripe -i $dir)
23590                 [ $default_index -eq -1 ] ||
23591                         [ $stripe_index -eq $default_index ] ||
23592                         error "$stripe_index != $default_index for $dir"
23593
23594                 #check default stripe
23595                 stripe_count=$($LFS getdirstripe -D -c $dir)
23596                 [ $stripe_count -eq $default_count ] ||
23597                 error "default count $default_count != $stripe_count for $dir"
23598
23599                 stripe_index=$($LFS getdirstripe -D -i $dir)
23600                 [ $stripe_index -eq $default_index ] ||
23601                 error "default index $default_index != $stripe_index for $dir"
23602         done
23603         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23604 }
23605
23606 test_300g() {
23607         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23608         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23609                 skip "Need MDS version at least 2.7.55"
23610
23611         local dir
23612         local stripe_count
23613         local stripe_index
23614
23615         mkdir_on_mdt0 $DIR/$tdir
23616         mkdir $DIR/$tdir/normal_dir
23617
23618         #Checking when client cache stripe index
23619         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23620         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23621                 error "create striped_dir failed"
23622
23623         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23624                 error "create dir0 fails"
23625         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23626         [ $stripe_index -eq 0 ] ||
23627                 error "dir0 expect index 0 got $stripe_index"
23628
23629         mkdir $DIR/$tdir/striped_dir/dir1 ||
23630                 error "create dir1 fails"
23631         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23632         [ $stripe_index -eq 1 ] ||
23633                 error "dir1 expect index 1 got $stripe_index"
23634
23635         #check default stripe count/stripe index
23636         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23637         test_300_check_default_striped_dir normal_dir 1 0
23638         test_300_check_default_striped_dir normal_dir -1 1
23639         test_300_check_default_striped_dir normal_dir 2 -1
23640
23641         #delete default stripe information
23642         echo "delete default stripeEA"
23643         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23644                 error "set default stripe on striped dir error"
23645
23646         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23647         for dir in $(find $DIR/$tdir/normal_dir/*); do
23648                 stripe_count=$($LFS getdirstripe -c $dir)
23649                 [ $stripe_count -eq 0 ] ||
23650                         error "expect 1 get $stripe_count for $dir"
23651         done
23652 }
23653 run_test 300g "check default striped directory for normal directory"
23654
23655 test_300h() {
23656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23657         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23658                 skip "Need MDS version at least 2.7.55"
23659
23660         local dir
23661         local stripe_count
23662
23663         mkdir $DIR/$tdir
23664         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23665                 error "set striped dir error"
23666
23667         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23668         test_300_check_default_striped_dir striped_dir 1 0
23669         test_300_check_default_striped_dir striped_dir -1 1
23670         test_300_check_default_striped_dir striped_dir 2 -1
23671
23672         #delete default stripe information
23673         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23674                 error "set default stripe on striped dir error"
23675
23676         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23677         for dir in $(find $DIR/$tdir/striped_dir/*); do
23678                 stripe_count=$($LFS getdirstripe -c $dir)
23679                 [ $stripe_count -eq 0 ] ||
23680                         error "expect 1 get $stripe_count for $dir"
23681         done
23682 }
23683 run_test 300h "check default striped directory for striped directory"
23684
23685 test_300i() {
23686         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23687         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23688         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23689                 skip "Need MDS version at least 2.7.55"
23690
23691         local stripe_count
23692         local file
23693
23694         mkdir $DIR/$tdir
23695
23696         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23697                 error "set striped dir error"
23698
23699         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23700                 error "create files under striped dir failed"
23701
23702         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23703                 error "set striped hashdir error"
23704
23705         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23706                 error "create dir0 under hash dir failed"
23707         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23708                 error "create dir1 under hash dir failed"
23709         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23710                 error "create dir2 under hash dir failed"
23711
23712         # unfortunately, we need to umount to clear dir layout cache for now
23713         # once we fully implement dir layout, we can drop this
23714         umount_client $MOUNT || error "umount failed"
23715         mount_client $MOUNT || error "mount failed"
23716
23717         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23718         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23719         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23720
23721         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23722                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23723                         error "create crush2 dir $tdir/hashdir/d3 failed"
23724                 $LFS find -H crush2 $DIR/$tdir/hashdir
23725                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23726                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23727
23728                 # mkdir with an invalid hash type (hash=fail_val) from client
23729                 # should be replaced on MDS with a valid (default) hash type
23730                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23731                 $LCTL set_param fail_loc=0x1901 fail_val=99
23732                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23733
23734                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23735                 local expect=$(do_facet mds1 \
23736                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23737                 [[ $hash == $expect ]] ||
23738                         error "d99 hash '$hash' != expected hash '$expect'"
23739         fi
23740
23741         #set the stripe to be unknown hash type on read
23742         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23743         $LCTL set_param fail_loc=0x1901 fail_val=99
23744         for ((i = 0; i < 10; i++)); do
23745                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23746                         error "stat f-$i failed"
23747                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23748         done
23749
23750         touch $DIR/$tdir/striped_dir/f0 &&
23751                 error "create under striped dir with unknown hash should fail"
23752
23753         $LCTL set_param fail_loc=0
23754
23755         umount_client $MOUNT || error "umount failed"
23756         mount_client $MOUNT || error "mount failed"
23757
23758         return 0
23759 }
23760 run_test 300i "client handle unknown hash type striped directory"
23761
23762 test_300j() {
23763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23765         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23766                 skip "Need MDS version at least 2.7.55"
23767
23768         local stripe_count
23769         local file
23770
23771         mkdir $DIR/$tdir
23772
23773         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23774         $LCTL set_param fail_loc=0x1702
23775         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23776                 error "set striped dir error"
23777
23778         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23779                 error "create files under striped dir failed"
23780
23781         $LCTL set_param fail_loc=0
23782
23783         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23784
23785         return 0
23786 }
23787 run_test 300j "test large update record"
23788
23789 test_300k() {
23790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23792         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23793                 skip "Need MDS version at least 2.7.55"
23794
23795         # this test needs a huge transaction
23796         local kb
23797         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23798              osd*.$FSNAME-MDT0000.kbytestotal")
23799         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23800
23801         local stripe_count
23802         local file
23803
23804         mkdir $DIR/$tdir
23805
23806         #define OBD_FAIL_LARGE_STRIPE   0x1703
23807         $LCTL set_param fail_loc=0x1703
23808         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23809                 error "set striped dir error"
23810         $LCTL set_param fail_loc=0
23811
23812         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23813                 error "getstripeddir fails"
23814         rm -rf $DIR/$tdir/striped_dir ||
23815                 error "unlink striped dir fails"
23816
23817         return 0
23818 }
23819 run_test 300k "test large striped directory"
23820
23821 test_300l() {
23822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23823         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23824         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23825                 skip "Need MDS version at least 2.7.55"
23826
23827         local stripe_index
23828
23829         test_mkdir -p $DIR/$tdir/striped_dir
23830         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23831                         error "chown $RUNAS_ID failed"
23832         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23833                 error "set default striped dir failed"
23834
23835         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23836         $LCTL set_param fail_loc=0x80000158
23837         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23838
23839         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23840         [ $stripe_index -eq 1 ] ||
23841                 error "expect 1 get $stripe_index for $dir"
23842 }
23843 run_test 300l "non-root user to create dir under striped dir with stale layout"
23844
23845 test_300m() {
23846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23847         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23848         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23849                 skip "Need MDS version at least 2.7.55"
23850
23851         mkdir -p $DIR/$tdir/striped_dir
23852         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23853                 error "set default stripes dir error"
23854
23855         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23856
23857         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23858         [ $stripe_count -eq 0 ] ||
23859                         error "expect 0 get $stripe_count for a"
23860
23861         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23862                 error "set default stripes dir error"
23863
23864         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23865
23866         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23867         [ $stripe_count -eq 0 ] ||
23868                         error "expect 0 get $stripe_count for b"
23869
23870         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23871                 error "set default stripes dir error"
23872
23873         mkdir $DIR/$tdir/striped_dir/c &&
23874                 error "default stripe_index is invalid, mkdir c should fails"
23875
23876         rm -rf $DIR/$tdir || error "rmdir fails"
23877 }
23878 run_test 300m "setstriped directory on single MDT FS"
23879
23880 cleanup_300n() {
23881         local list=$(comma_list $(mdts_nodes))
23882
23883         trap 0
23884         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23885 }
23886
23887 test_300n() {
23888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23890         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23891                 skip "Need MDS version at least 2.7.55"
23892         remote_mds_nodsh && skip "remote MDS with nodsh"
23893
23894         local stripe_index
23895         local list=$(comma_list $(mdts_nodes))
23896
23897         trap cleanup_300n RETURN EXIT
23898         mkdir -p $DIR/$tdir
23899         chmod 777 $DIR/$tdir
23900         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23901                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23902                 error "create striped dir succeeds with gid=0"
23903
23904         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23905         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23906                 error "create striped dir fails with gid=-1"
23907
23908         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23909         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23910                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23911                 error "set default striped dir succeeds with gid=0"
23912
23913
23914         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23915         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23916                 error "set default striped dir fails with gid=-1"
23917
23918
23919         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23920         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23921                                         error "create test_dir fails"
23922         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23923                                         error "create test_dir1 fails"
23924         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23925                                         error "create test_dir2 fails"
23926         cleanup_300n
23927 }
23928 run_test 300n "non-root user to create dir under striped dir with default EA"
23929
23930 test_300o() {
23931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23932         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23933         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23934                 skip "Need MDS version at least 2.7.55"
23935
23936         local numfree1
23937         local numfree2
23938
23939         mkdir -p $DIR/$tdir
23940
23941         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23942         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23943         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23944                 skip "not enough free inodes $numfree1 $numfree2"
23945         fi
23946
23947         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23948         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23949         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23950                 skip "not enough free space $numfree1 $numfree2"
23951         fi
23952
23953         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23954                 error "setdirstripe fails"
23955
23956         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23957                 error "create dirs fails"
23958
23959         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23960         ls $DIR/$tdir/striped_dir > /dev/null ||
23961                 error "ls striped dir fails"
23962         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23963                 error "unlink big striped dir fails"
23964 }
23965 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23966
23967 test_300p() {
23968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23970         remote_mds_nodsh && skip "remote MDS with nodsh"
23971
23972         mkdir_on_mdt0 $DIR/$tdir
23973
23974         #define OBD_FAIL_OUT_ENOSPC     0x1704
23975         do_facet mds2 lctl set_param fail_loc=0x80001704
23976         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23977                  && error "create striped directory should fail"
23978
23979         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23980
23981         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23982         true
23983 }
23984 run_test 300p "create striped directory without space"
23985
23986 test_300q() {
23987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23989
23990         local fd=$(free_fd)
23991         local cmd="exec $fd<$tdir"
23992         cd $DIR
23993         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23994         eval $cmd
23995         cmd="exec $fd<&-"
23996         trap "eval $cmd" EXIT
23997         cd $tdir || error "cd $tdir fails"
23998         rmdir  ../$tdir || error "rmdir $tdir fails"
23999         mkdir local_dir && error "create dir succeeds"
24000         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24001         eval $cmd
24002         return 0
24003 }
24004 run_test 300q "create remote directory under orphan directory"
24005
24006 test_300r() {
24007         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24008                 skip "Need MDS version at least 2.7.55" && return
24009         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24010
24011         mkdir $DIR/$tdir
24012
24013         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24014                 error "set striped dir error"
24015
24016         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24017                 error "getstripeddir fails"
24018
24019         local stripe_count
24020         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24021                       awk '/lmv_stripe_count:/ { print $2 }')
24022
24023         [ $MDSCOUNT -ne $stripe_count ] &&
24024                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24025
24026         rm -rf $DIR/$tdir/striped_dir ||
24027                 error "unlink striped dir fails"
24028 }
24029 run_test 300r "test -1 striped directory"
24030
24031 test_300s_helper() {
24032         local count=$1
24033
24034         local stripe_dir=$DIR/$tdir/striped_dir.$count
24035
24036         $LFS mkdir -c $count $stripe_dir ||
24037                 error "lfs mkdir -c error"
24038
24039         $LFS getdirstripe $stripe_dir ||
24040                 error "lfs getdirstripe fails"
24041
24042         local stripe_count
24043         stripe_count=$($LFS getdirstripe $stripe_dir |
24044                       awk '/lmv_stripe_count:/ { print $2 }')
24045
24046         [ $count -ne $stripe_count ] &&
24047                 error_noexit "bad stripe count $stripe_count expected $count"
24048
24049         local dupe_stripes
24050         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24051                 awk '/0x/ {count[$1] += 1}; END {
24052                         for (idx in count) {
24053                                 if (count[idx]>1) {
24054                                         print "index " idx " count " count[idx]
24055                                 }
24056                         }
24057                 }')
24058
24059         if [[ -n "$dupe_stripes" ]] ; then
24060                 lfs getdirstripe $stripe_dir
24061                 error_noexit "Dupe MDT above: $dupe_stripes "
24062         fi
24063
24064         rm -rf $stripe_dir ||
24065                 error_noexit "unlink $stripe_dir fails"
24066 }
24067
24068 test_300s() {
24069         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24070                 skip "Need MDS version at least 2.7.55" && return
24071         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24072
24073         mkdir $DIR/$tdir
24074         for count in $(seq 2 $MDSCOUNT); do
24075                 test_300s_helper $count
24076         done
24077 }
24078 run_test 300s "test lfs mkdir -c without -i"
24079
24080 test_300t() {
24081         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24082                 skip "need MDS 2.14.55 or later"
24083         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24084
24085         local testdir="$DIR/$tdir/striped_dir"
24086         local dir1=$testdir/dir1
24087         local dir2=$testdir/dir2
24088
24089         mkdir -p $testdir
24090
24091         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24092                 error "failed to set default stripe count for $testdir"
24093
24094         mkdir $dir1
24095         local stripe_count=$($LFS getdirstripe -c $dir1)
24096
24097         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24098
24099         local max_count=$((MDSCOUNT - 1))
24100         local mdts=$(comma_list $(mdts_nodes))
24101
24102         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24103         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24104
24105         mkdir $dir2
24106         stripe_count=$($LFS getdirstripe -c $dir2)
24107
24108         (( $stripe_count == $max_count )) || error "wrong stripe count"
24109 }
24110 run_test 300t "test max_mdt_stripecount"
24111
24112 prepare_remote_file() {
24113         mkdir $DIR/$tdir/src_dir ||
24114                 error "create remote source failed"
24115
24116         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24117                  error "cp to remote source failed"
24118         touch $DIR/$tdir/src_dir/a
24119
24120         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24121                 error "create remote target dir failed"
24122
24123         touch $DIR/$tdir/tgt_dir/b
24124
24125         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24126                 error "rename dir cross MDT failed!"
24127
24128         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24129                 error "src_child still exists after rename"
24130
24131         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24132                 error "missing file(a) after rename"
24133
24134         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24135                 error "diff after rename"
24136 }
24137
24138 test_310a() {
24139         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24141
24142         local remote_file=$DIR/$tdir/tgt_dir/b
24143
24144         mkdir -p $DIR/$tdir
24145
24146         prepare_remote_file || error "prepare remote file failed"
24147
24148         #open-unlink file
24149         $OPENUNLINK $remote_file $remote_file ||
24150                 error "openunlink $remote_file failed"
24151         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24152 }
24153 run_test 310a "open unlink remote file"
24154
24155 test_310b() {
24156         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24158
24159         local remote_file=$DIR/$tdir/tgt_dir/b
24160
24161         mkdir -p $DIR/$tdir
24162
24163         prepare_remote_file || error "prepare remote file failed"
24164
24165         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24166         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24167         $CHECKSTAT -t file $remote_file || error "check file failed"
24168 }
24169 run_test 310b "unlink remote file with multiple links while open"
24170
24171 test_310c() {
24172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24173         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24174
24175         local remote_file=$DIR/$tdir/tgt_dir/b
24176
24177         mkdir -p $DIR/$tdir
24178
24179         prepare_remote_file || error "prepare remote file failed"
24180
24181         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24182         multiop_bg_pause $remote_file O_uc ||
24183                         error "mulitop failed for remote file"
24184         MULTIPID=$!
24185         $MULTIOP $DIR/$tfile Ouc
24186         kill -USR1 $MULTIPID
24187         wait $MULTIPID
24188 }
24189 run_test 310c "open-unlink remote file with multiple links"
24190
24191 #LU-4825
24192 test_311() {
24193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24194         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24195         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24196                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24197         remote_mds_nodsh && skip "remote MDS with nodsh"
24198
24199         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24200         local mdts=$(comma_list $(mdts_nodes))
24201
24202         mkdir -p $DIR/$tdir
24203         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24204         createmany -o $DIR/$tdir/$tfile. 1000
24205
24206         # statfs data is not real time, let's just calculate it
24207         old_iused=$((old_iused + 1000))
24208
24209         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24210                         osp.*OST0000*MDT0000.create_count")
24211         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24212                                 osp.*OST0000*MDT0000.max_create_count")
24213         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24214
24215         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24216         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24217         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24218
24219         unlinkmany $DIR/$tdir/$tfile. 1000
24220
24221         do_nodes $mdts "$LCTL set_param -n \
24222                         osp.*OST0000*.max_create_count=$max_count"
24223         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24224                 do_nodes $mdts "$LCTL set_param -n \
24225                                 osp.*OST0000*.create_count=$count"
24226         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24227                         grep "=0" && error "create_count is zero"
24228
24229         local new_iused
24230         for i in $(seq 120); do
24231                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24232                 # system may be too busy to destroy all objs in time, use
24233                 # a somewhat small value to not fail autotest
24234                 [ $((old_iused - new_iused)) -gt 400 ] && break
24235                 sleep 1
24236         done
24237
24238         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24239         [ $((old_iused - new_iused)) -gt 400 ] ||
24240                 error "objs not destroyed after unlink"
24241 }
24242 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24243
24244 zfs_oid_to_objid()
24245 {
24246         local ost=$1
24247         local objid=$2
24248
24249         local vdevdir=$(dirname $(facet_vdevice $ost))
24250         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24251         local zfs_zapid=$(do_facet $ost $cmd |
24252                           grep -w "/O/0/d$((objid%32))" -C 5 |
24253                           awk '/Object/{getline; print $1}')
24254         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24255                           awk "/$objid = /"'{printf $3}')
24256
24257         echo $zfs_objid
24258 }
24259
24260 zfs_object_blksz() {
24261         local ost=$1
24262         local objid=$2
24263
24264         local vdevdir=$(dirname $(facet_vdevice $ost))
24265         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24266         local blksz=$(do_facet $ost $cmd $objid |
24267                       awk '/dblk/{getline; printf $4}')
24268
24269         case "${blksz: -1}" in
24270                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24271                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24272                 *) ;;
24273         esac
24274
24275         echo $blksz
24276 }
24277
24278 test_312() { # LU-4856
24279         remote_ost_nodsh && skip "remote OST with nodsh"
24280         [ "$ost1_FSTYPE" = "zfs" ] ||
24281                 skip_env "the test only applies to zfs"
24282
24283         local max_blksz=$(do_facet ost1 \
24284                           $ZFS get -p recordsize $(facet_device ost1) |
24285                           awk '!/VALUE/{print $3}')
24286
24287         # to make life a little bit easier
24288         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24289         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24290
24291         local tf=$DIR/$tdir/$tfile
24292         touch $tf
24293         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24294
24295         # Get ZFS object id
24296         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24297         # block size change by sequential overwrite
24298         local bs
24299
24300         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24301                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24302
24303                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24304                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24305         done
24306         rm -f $tf
24307
24308         # block size change by sequential append write
24309         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24310         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24311         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24312         local count
24313
24314         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24315                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24316                         oflag=sync conv=notrunc
24317
24318                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24319                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24320                         error "blksz error, actual $blksz, " \
24321                                 "expected: 2 * $count * $PAGE_SIZE"
24322         done
24323         rm -f $tf
24324
24325         # random write
24326         touch $tf
24327         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24328         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24329
24330         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24331         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24332         [ $blksz -eq $PAGE_SIZE ] ||
24333                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24334
24335         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24336         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24337         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24338
24339         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24340         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24341         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24342 }
24343 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24344
24345 test_313() {
24346         remote_ost_nodsh && skip "remote OST with nodsh"
24347
24348         local file=$DIR/$tfile
24349
24350         rm -f $file
24351         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24352
24353         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24354         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24355         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24356                 error "write should failed"
24357         do_facet ost1 "$LCTL set_param fail_loc=0"
24358         rm -f $file
24359 }
24360 run_test 313 "io should fail after last_rcvd update fail"
24361
24362 test_314() {
24363         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24364
24365         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24366         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24367         rm -f $DIR/$tfile
24368         wait_delete_completed
24369         do_facet ost1 "$LCTL set_param fail_loc=0"
24370 }
24371 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24372
24373 test_315() { # LU-618
24374         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24375
24376         local file=$DIR/$tfile
24377         rm -f $file
24378
24379         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24380                 error "multiop file write failed"
24381         $MULTIOP $file oO_RDONLY:r4063232_c &
24382         PID=$!
24383
24384         sleep 2
24385
24386         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24387         kill -USR1 $PID
24388
24389         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24390         rm -f $file
24391 }
24392 run_test 315 "read should be accounted"
24393
24394 test_316() {
24395         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24396         large_xattr_enabled || skip "ea_inode feature disabled"
24397
24398         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24399         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24400         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24401         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24402
24403         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24404 }
24405 run_test 316 "lfs migrate of file with large_xattr enabled"
24406
24407 test_317() {
24408         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24409                 skip "Need MDS version at least 2.11.53"
24410         if [ "$ost1_FSTYPE" == "zfs" ]; then
24411                 skip "LU-10370: no implementation for ZFS"
24412         fi
24413
24414         local trunc_sz
24415         local grant_blk_size
24416
24417         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24418                         awk '/grant_block_size:/ { print $2; exit; }')
24419         #
24420         # Create File of size 5M. Truncate it to below size's and verify
24421         # blocks count.
24422         #
24423         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24424                 error "Create file $DIR/$tfile failed"
24425         stack_trap "rm -f $DIR/$tfile" EXIT
24426
24427         for trunc_sz in 2097152 4097 4000 509 0; do
24428                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24429                         error "truncate $tfile to $trunc_sz failed"
24430                 local sz=$(stat --format=%s $DIR/$tfile)
24431                 local blk=$(stat --format=%b $DIR/$tfile)
24432                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24433                                      grant_blk_size) * 8))
24434
24435                 if [[ $blk -ne $trunc_blk ]]; then
24436                         $(which stat) $DIR/$tfile
24437                         error "Expected Block $trunc_blk got $blk for $tfile"
24438                 fi
24439
24440                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24441                         error "Expected Size $trunc_sz got $sz for $tfile"
24442         done
24443
24444         #
24445         # sparse file test
24446         # Create file with a hole and write actual 65536 bytes which aligned
24447         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24448         #
24449         local bs=65536
24450         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24451                 error "Create file : $DIR/$tfile"
24452
24453         #
24454         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24455         # blocks. The block count must drop to 8.
24456         #
24457         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24458                 ((bs - grant_blk_size) + 1)))
24459         $TRUNCATE $DIR/$tfile $trunc_sz ||
24460                 error "truncate $tfile to $trunc_sz failed"
24461
24462         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24463         sz=$(stat --format=%s $DIR/$tfile)
24464         blk=$(stat --format=%b $DIR/$tfile)
24465
24466         if [[ $blk -ne $trunc_bsz ]]; then
24467                 $(which stat) $DIR/$tfile
24468                 error "Expected Block $trunc_bsz got $blk for $tfile"
24469         fi
24470
24471         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24472                 error "Expected Size $trunc_sz got $sz for $tfile"
24473 }
24474 run_test 317 "Verify blocks get correctly update after truncate"
24475
24476 test_318() {
24477         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24478         local old_max_active=$($LCTL get_param -n \
24479                             ${llite_name}.max_read_ahead_async_active \
24480                             2>/dev/null)
24481
24482         $LCTL set_param llite.*.max_read_ahead_async_active=256
24483         local max_active=$($LCTL get_param -n \
24484                            ${llite_name}.max_read_ahead_async_active \
24485                            2>/dev/null)
24486         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24487
24488         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24489                 error "set max_read_ahead_async_active should succeed"
24490
24491         $LCTL set_param llite.*.max_read_ahead_async_active=512
24492         max_active=$($LCTL get_param -n \
24493                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24494         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24495
24496         # restore @max_active
24497         [ $old_max_active -ne 0 ] && $LCTL set_param \
24498                 llite.*.max_read_ahead_async_active=$old_max_active
24499
24500         local old_threshold=$($LCTL get_param -n \
24501                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24502         local max_per_file_mb=$($LCTL get_param -n \
24503                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24504
24505         local invalid=$(($max_per_file_mb + 1))
24506         $LCTL set_param \
24507                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24508                         && error "set $invalid should fail"
24509
24510         local valid=$(($invalid - 1))
24511         $LCTL set_param \
24512                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24513                         error "set $valid should succeed"
24514         local threshold=$($LCTL get_param -n \
24515                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24516         [ $threshold -eq $valid ] || error \
24517                 "expect threshold $valid got $threshold"
24518         $LCTL set_param \
24519                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24520 }
24521 run_test 318 "Verify async readahead tunables"
24522
24523 test_319() {
24524         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24525
24526         local before=$(date +%s)
24527         local evict
24528         local mdir=$DIR/$tdir
24529         local file=$mdir/xxx
24530
24531         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24532         touch $file
24533
24534 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24535         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24536         $LFS migrate -m1 $mdir &
24537
24538         sleep 1
24539         dd if=$file of=/dev/null
24540         wait
24541         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24542           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24543
24544         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24545 }
24546 run_test 319 "lost lease lock on migrate error"
24547
24548 test_398a() { # LU-4198
24549         local ost1_imp=$(get_osc_import_name client ost1)
24550         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24551                          cut -d'.' -f2)
24552
24553         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24554         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24555
24556         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24557         # request a new lock on client
24558         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24559
24560         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24561         #local lock_count=$($LCTL get_param -n \
24562         #                  ldlm.namespaces.$imp_name.lru_size)
24563         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24564
24565         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24566
24567         # no lock cached, should use lockless DIO and not enqueue new lock
24568         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24569                 conv=notrunc ||
24570                 error "dio write failed"
24571         lock_count=$($LCTL get_param -n \
24572                      ldlm.namespaces.$imp_name.lru_size)
24573         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24574
24575         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24576
24577         # no lock cached, should use locked DIO append
24578         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24579                 conv=notrunc || error "DIO append failed"
24580         lock_count=$($LCTL get_param -n \
24581                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24582         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24583 }
24584 run_test 398a "direct IO should cancel lock otherwise lockless"
24585
24586 test_398b() { # LU-4198
24587         which fio || skip_env "no fio installed"
24588         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24589
24590         local size=48
24591         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24592
24593         local njobs=4
24594         # Single page, multiple pages, stripe size, 4*stripe size
24595         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24596                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24597                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24598                         --numjobs=$njobs --fallocate=none \
24599                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24600                         --filename=$DIR/$tfile &
24601                 bg_pid=$!
24602
24603                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24604                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24605                         --numjobs=$njobs --fallocate=none \
24606                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24607                         --filename=$DIR/$tfile || true
24608                 wait $bg_pid
24609         done
24610
24611         evict=$(do_facet client $LCTL get_param \
24612                 osc.$FSNAME-OST*-osc-*/state |
24613             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24614
24615         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24616                 (do_facet client $LCTL get_param \
24617                         osc.$FSNAME-OST*-osc-*/state;
24618                     error "eviction happened: $evict before:$before")
24619
24620         rm -f $DIR/$tfile
24621 }
24622 run_test 398b "DIO and buffer IO race"
24623
24624 test_398c() { # LU-4198
24625         local ost1_imp=$(get_osc_import_name client ost1)
24626         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24627                          cut -d'.' -f2)
24628
24629         which fio || skip_env "no fio installed"
24630
24631         saved_debug=$($LCTL get_param -n debug)
24632         $LCTL set_param debug=0
24633
24634         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24635         ((size /= 1024)) # by megabytes
24636         ((size /= 2)) # write half of the OST at most
24637         [ $size -gt 40 ] && size=40 #reduce test time anyway
24638
24639         $LFS setstripe -c 1 $DIR/$tfile
24640
24641         # it seems like ldiskfs reserves more space than necessary if the
24642         # writing blocks are not mapped, so it extends the file firstly
24643         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24644         cancel_lru_locks osc
24645
24646         # clear and verify rpc_stats later
24647         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24648
24649         local njobs=4
24650         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24651         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24652                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24653                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24654                 --filename=$DIR/$tfile
24655         [ $? -eq 0 ] || error "fio write error"
24656
24657         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24658                 error "Locks were requested while doing AIO"
24659
24660         # get the percentage of 1-page I/O
24661         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24662                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24663                 awk '{print $7}')
24664         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24665
24666         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24667         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24668                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24669                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24670                 --filename=$DIR/$tfile
24671         [ $? -eq 0 ] || error "fio mixed read write error"
24672
24673         echo "AIO with large block size ${size}M"
24674         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24675                 --numjobs=1 --fallocate=none --ioengine=libaio \
24676                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24677                 --filename=$DIR/$tfile
24678         [ $? -eq 0 ] || error "fio large block size failed"
24679
24680         rm -f $DIR/$tfile
24681         $LCTL set_param debug="$saved_debug"
24682 }
24683 run_test 398c "run fio to test AIO"
24684
24685 test_398d() { #  LU-13846
24686         which aiocp || skip_env "no aiocp installed"
24687         local aio_file=$DIR/$tfile.aio
24688
24689         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24690
24691         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24692         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24693         stack_trap "rm -f $DIR/$tfile $aio_file"
24694
24695         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24696
24697         # make sure we don't crash and fail properly
24698         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24699                 error "aio not aligned with PAGE SIZE should fail"
24700
24701         rm -f $DIR/$tfile $aio_file
24702 }
24703 run_test 398d "run aiocp to verify block size > stripe size"
24704
24705 test_398e() {
24706         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24707         touch $DIR/$tfile.new
24708         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24709 }
24710 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24711
24712 test_398f() { #  LU-14687
24713         which aiocp || skip_env "no aiocp installed"
24714         local aio_file=$DIR/$tfile.aio
24715
24716         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24717
24718         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24719         stack_trap "rm -f $DIR/$tfile $aio_file"
24720
24721         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24722         $LCTL set_param fail_loc=0x1418
24723         # make sure we don't crash and fail properly
24724         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24725                 error "aio with page allocation failure succeeded"
24726         $LCTL set_param fail_loc=0
24727         diff $DIR/$tfile $aio_file
24728         [[ $? != 0 ]] || error "no diff after failed aiocp"
24729 }
24730 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24731
24732 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24733 # stripe and i/o size must be > stripe size
24734 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24735 # single RPC in flight.  This test shows async DIO submission is working by
24736 # showing multiple RPCs in flight.
24737 test_398g() { #  LU-13798
24738         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24739
24740         # We need to do some i/o first to acquire enough grant to put our RPCs
24741         # in flight; otherwise a new connection may not have enough grant
24742         # available
24743         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24744                 error "parallel dio failed"
24745         stack_trap "rm -f $DIR/$tfile"
24746
24747         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24748         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24749         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24750         stack_trap "$LCTL set_param -n $pages_per_rpc"
24751
24752         # Recreate file so it's empty
24753         rm -f $DIR/$tfile
24754         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24755         #Pause rpc completion to guarantee we see multiple rpcs in flight
24756         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24757         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24758         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24759
24760         # Clear rpc stats
24761         $LCTL set_param osc.*.rpc_stats=c
24762
24763         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24764                 error "parallel dio failed"
24765         stack_trap "rm -f $DIR/$tfile"
24766
24767         $LCTL get_param osc.*-OST0000-*.rpc_stats
24768         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24769                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24770                 grep "8:" | awk '{print $8}')
24771         # We look at the "8 rpcs in flight" field, and verify A) it is present
24772         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24773         # as expected for an 8M DIO to a file with 1M stripes.
24774         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24775
24776         # Verify turning off parallel dio works as expected
24777         # Clear rpc stats
24778         $LCTL set_param osc.*.rpc_stats=c
24779         $LCTL set_param llite.*.parallel_dio=0
24780         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24781
24782         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24783                 error "dio with parallel dio disabled failed"
24784
24785         # Ideally, we would see only one RPC in flight here, but there is an
24786         # unavoidable race between i/o completion and RPC in flight counting,
24787         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24788         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24789         # So instead we just verify it's always < 8.
24790         $LCTL get_param osc.*-OST0000-*.rpc_stats
24791         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24792                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24793                 grep '^$' -B1 | grep . | awk '{print $1}')
24794         [ $ret != "8:" ] ||
24795                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24796 }
24797 run_test 398g "verify parallel dio async RPC submission"
24798
24799 test_398h() { #  LU-13798
24800         local dio_file=$DIR/$tfile.dio
24801
24802         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24803
24804         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24805         stack_trap "rm -f $DIR/$tfile $dio_file"
24806
24807         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24808                 error "parallel dio failed"
24809         diff $DIR/$tfile $dio_file
24810         [[ $? == 0 ]] || error "file diff after aiocp"
24811 }
24812 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24813
24814 test_398i() { #  LU-13798
24815         local dio_file=$DIR/$tfile.dio
24816
24817         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24818
24819         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24820         stack_trap "rm -f $DIR/$tfile $dio_file"
24821
24822         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24823         $LCTL set_param fail_loc=0x1418
24824         # make sure we don't crash and fail properly
24825         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24826                 error "parallel dio page allocation failure succeeded"
24827         diff $DIR/$tfile $dio_file
24828         [[ $? != 0 ]] || error "no diff after failed aiocp"
24829 }
24830 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24831
24832 test_398j() { #  LU-13798
24833         # Stripe size > RPC size but less than i/o size tests split across
24834         # stripes and RPCs for individual i/o op
24835         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24836
24837         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24838         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24839         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24840         stack_trap "$LCTL set_param -n $pages_per_rpc"
24841
24842         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24843                 error "parallel dio write failed"
24844         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24845
24846         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24847                 error "parallel dio read failed"
24848         diff $DIR/$tfile $DIR/$tfile.2
24849         [[ $? == 0 ]] || error "file diff after parallel dio read"
24850 }
24851 run_test 398j "test parallel dio where stripe size > rpc_size"
24852
24853 test_398k() { #  LU-13798
24854         wait_delete_completed
24855         wait_mds_ost_sync
24856
24857         # 4 stripe file; we will cause out of space on OST0
24858         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24859
24860         # Fill OST0 (if it's not too large)
24861         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24862                    head -n1)
24863         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24864                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24865         fi
24866         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24867         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24868                 error "dd should fill OST0"
24869         stack_trap "rm -f $DIR/$tfile.1"
24870
24871         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24872         err=$?
24873
24874         ls -la $DIR/$tfile
24875         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24876                 error "file is not 0 bytes in size"
24877
24878         # dd above should not succeed, but don't error until here so we can
24879         # get debug info above
24880         [[ $err != 0 ]] ||
24881                 error "parallel dio write with enospc succeeded"
24882         stack_trap "rm -f $DIR/$tfile"
24883 }
24884 run_test 398k "test enospc on first stripe"
24885
24886 test_398l() { #  LU-13798
24887         wait_delete_completed
24888         wait_mds_ost_sync
24889
24890         # 4 stripe file; we will cause out of space on OST0
24891         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24892         # happens on the second i/o chunk we issue
24893         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24894
24895         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24896         stack_trap "rm -f $DIR/$tfile"
24897
24898         # Fill OST0 (if it's not too large)
24899         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24900                    head -n1)
24901         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24902                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24903         fi
24904         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24905         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24906                 error "dd should fill OST0"
24907         stack_trap "rm -f $DIR/$tfile.1"
24908
24909         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24910         err=$?
24911         stack_trap "rm -f $DIR/$tfile.2"
24912
24913         # Check that short write completed as expected
24914         ls -la $DIR/$tfile.2
24915         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24916                 error "file is not 1M in size"
24917
24918         # dd above should not succeed, but don't error until here so we can
24919         # get debug info above
24920         [[ $err != 0 ]] ||
24921                 error "parallel dio write with enospc succeeded"
24922
24923         # Truncate source file to same length as output file and diff them
24924         $TRUNCATE $DIR/$tfile 1048576
24925         diff $DIR/$tfile $DIR/$tfile.2
24926         [[ $? == 0 ]] || error "data incorrect after short write"
24927 }
24928 run_test 398l "test enospc on intermediate stripe/RPC"
24929
24930 test_398m() { #  LU-13798
24931         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24932
24933         # Set up failure on OST0, the first stripe:
24934         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24935         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24936         # So this fail_val specifies OST0
24937         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24938         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24939
24940         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24941                 error "parallel dio write with failure on first stripe succeeded"
24942         stack_trap "rm -f $DIR/$tfile"
24943         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24944
24945         # Place data in file for read
24946         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24947                 error "parallel dio write failed"
24948
24949         # Fail read on OST0, first stripe
24950         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24951         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24952         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24953                 error "parallel dio read with error on first stripe succeeded"
24954         rm -f $DIR/$tfile.2
24955         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24956
24957         # Switch to testing on OST1, second stripe
24958         # Clear file contents, maintain striping
24959         echo > $DIR/$tfile
24960         # Set up failure on OST1, second stripe:
24961         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24962         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24963
24964         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24965                 error "parallel dio write with failure on first stripe succeeded"
24966         stack_trap "rm -f $DIR/$tfile"
24967         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24968
24969         # Place data in file for read
24970         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24971                 error "parallel dio write failed"
24972
24973         # Fail read on OST1, second stripe
24974         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24975         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24976         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24977                 error "parallel dio read with error on first stripe succeeded"
24978         rm -f $DIR/$tfile.2
24979         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24980 }
24981 run_test 398m "test RPC failures with parallel dio"
24982
24983 # Parallel submission of DIO should not cause problems for append, but it's
24984 # important to verify.
24985 test_398n() { #  LU-13798
24986         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24987
24988         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24989                 error "dd to create source file failed"
24990         stack_trap "rm -f $DIR/$tfile"
24991
24992         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24993                 error "parallel dio write with failure on second stripe succeeded"
24994         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24995         diff $DIR/$tfile $DIR/$tfile.1
24996         [[ $? == 0 ]] || error "data incorrect after append"
24997
24998 }
24999 run_test 398n "test append with parallel DIO"
25000
25001 test_fake_rw() {
25002         local read_write=$1
25003         if [ "$read_write" = "write" ]; then
25004                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25005         elif [ "$read_write" = "read" ]; then
25006                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25007         else
25008                 error "argument error"
25009         fi
25010
25011         # turn off debug for performance testing
25012         local saved_debug=$($LCTL get_param -n debug)
25013         $LCTL set_param debug=0
25014
25015         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25016
25017         # get ost1 size - $FSNAME-OST0000
25018         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25019         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25020         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25021
25022         if [ "$read_write" = "read" ]; then
25023                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25024         fi
25025
25026         local start_time=$(date +%s.%N)
25027         $dd_cmd bs=1M count=$blocks oflag=sync ||
25028                 error "real dd $read_write error"
25029         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25030
25031         if [ "$read_write" = "write" ]; then
25032                 rm -f $DIR/$tfile
25033         fi
25034
25035         # define OBD_FAIL_OST_FAKE_RW           0x238
25036         do_facet ost1 $LCTL set_param fail_loc=0x238
25037
25038         local start_time=$(date +%s.%N)
25039         $dd_cmd bs=1M count=$blocks oflag=sync ||
25040                 error "fake dd $read_write error"
25041         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25042
25043         if [ "$read_write" = "write" ]; then
25044                 # verify file size
25045                 cancel_lru_locks osc
25046                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25047                         error "$tfile size not $blocks MB"
25048         fi
25049         do_facet ost1 $LCTL set_param fail_loc=0
25050
25051         echo "fake $read_write $duration_fake vs. normal $read_write" \
25052                 "$duration in seconds"
25053         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25054                 error_not_in_vm "fake write is slower"
25055
25056         $LCTL set_param -n debug="$saved_debug"
25057         rm -f $DIR/$tfile
25058 }
25059 test_399a() { # LU-7655 for OST fake write
25060         remote_ost_nodsh && skip "remote OST with nodsh"
25061
25062         test_fake_rw write
25063 }
25064 run_test 399a "fake write should not be slower than normal write"
25065
25066 test_399b() { # LU-8726 for OST fake read
25067         remote_ost_nodsh && skip "remote OST with nodsh"
25068         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25069                 skip_env "ldiskfs only test"
25070         fi
25071
25072         test_fake_rw read
25073 }
25074 run_test 399b "fake read should not be slower than normal read"
25075
25076 test_400a() { # LU-1606, was conf-sanity test_74
25077         if ! which $CC > /dev/null 2>&1; then
25078                 skip_env "$CC is not installed"
25079         fi
25080
25081         local extra_flags=''
25082         local out=$TMP/$tfile
25083         local prefix=/usr/include/lustre
25084         local prog
25085
25086         # Oleg removes c files in his test rig so test if any c files exist
25087         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25088                 skip_env "Needed c test files are missing"
25089
25090         if ! [[ -d $prefix ]]; then
25091                 # Assume we're running in tree and fixup the include path.
25092                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25093                 extra_flags+=" -L$LUSTRE/utils/.lib"
25094         fi
25095
25096         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25097                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25098                         error "client api broken"
25099         done
25100         rm -f $out
25101 }
25102 run_test 400a "Lustre client api program can compile and link"
25103
25104 test_400b() { # LU-1606, LU-5011
25105         local header
25106         local out=$TMP/$tfile
25107         local prefix=/usr/include/linux/lustre
25108
25109         # We use a hard coded prefix so that this test will not fail
25110         # when run in tree. There are headers in lustre/include/lustre/
25111         # that are not packaged (like lustre_idl.h) and have more
25112         # complicated include dependencies (like config.h and lnet/types.h).
25113         # Since this test about correct packaging we just skip them when
25114         # they don't exist (see below) rather than try to fixup cppflags.
25115
25116         if ! which $CC > /dev/null 2>&1; then
25117                 skip_env "$CC is not installed"
25118         fi
25119
25120         for header in $prefix/*.h; do
25121                 if ! [[ -f "$header" ]]; then
25122                         continue
25123                 fi
25124
25125                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25126                         continue # lustre_ioctl.h is internal header
25127                 fi
25128
25129                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25130                         error "cannot compile '$header'"
25131         done
25132         rm -f $out
25133 }
25134 run_test 400b "packaged headers can be compiled"
25135
25136 test_401a() { #LU-7437
25137         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25138         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25139
25140         #count the number of parameters by "list_param -R"
25141         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25142         #count the number of parameters by listing proc files
25143         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25144         echo "proc_dirs='$proc_dirs'"
25145         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25146         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25147                       sort -u | wc -l)
25148
25149         [ $params -eq $procs ] ||
25150                 error "found $params parameters vs. $procs proc files"
25151
25152         # test the list_param -D option only returns directories
25153         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25154         #count the number of parameters by listing proc directories
25155         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25156                 sort -u | wc -l)
25157
25158         [ $params -eq $procs ] ||
25159                 error "found $params parameters vs. $procs proc files"
25160 }
25161 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25162
25163 test_401b() {
25164         # jobid_var may not allow arbitrary values, so use jobid_name
25165         # if available
25166         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25167                 local testname=jobid_name tmp='testing%p'
25168         else
25169                 local testname=jobid_var tmp=testing
25170         fi
25171
25172         local save=$($LCTL get_param -n $testname)
25173
25174         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25175                 error "no error returned when setting bad parameters"
25176
25177         local jobid_new=$($LCTL get_param -n foe $testname baz)
25178         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25179
25180         $LCTL set_param -n fog=bam $testname=$save bat=fog
25181         local jobid_old=$($LCTL get_param -n foe $testname bag)
25182         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25183 }
25184 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25185
25186 test_401c() {
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
25191         else
25192                 local testname=jobid_var
25193         fi
25194
25195         local jobid_var_old=$($LCTL get_param -n $testname)
25196         local jobid_var_new
25197
25198         $LCTL set_param $testname= &&
25199                 error "no error returned for 'set_param a='"
25200
25201         jobid_var_new=$($LCTL get_param -n $testname)
25202         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25203                 error "$testname was changed by setting without value"
25204
25205         $LCTL set_param $testname &&
25206                 error "no error returned for 'set_param a'"
25207
25208         jobid_var_new=$($LCTL get_param -n $testname)
25209         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25210                 error "$testname was changed by setting without value"
25211 }
25212 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25213
25214 test_401d() {
25215         # jobid_var may not allow arbitrary values, so use jobid_name
25216         # if available
25217         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25218                 local testname=jobid_name new_value='foo=bar%p'
25219         else
25220                 local testname=jobid_var new_valuie=foo=bar
25221         fi
25222
25223         local jobid_var_old=$($LCTL get_param -n $testname)
25224         local jobid_var_new
25225
25226         $LCTL set_param $testname=$new_value ||
25227                 error "'set_param a=b' did not accept a value containing '='"
25228
25229         jobid_var_new=$($LCTL get_param -n $testname)
25230         [[ "$jobid_var_new" == "$new_value" ]] ||
25231                 error "'set_param a=b' failed on a value containing '='"
25232
25233         # Reset the $testname to test the other format
25234         $LCTL set_param $testname=$jobid_var_old
25235         jobid_var_new=$($LCTL get_param -n $testname)
25236         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25237                 error "failed to reset $testname"
25238
25239         $LCTL set_param $testname $new_value ||
25240                 error "'set_param a b' did not accept a value containing '='"
25241
25242         jobid_var_new=$($LCTL get_param -n $testname)
25243         [[ "$jobid_var_new" == "$new_value" ]] ||
25244                 error "'set_param a b' failed on a value containing '='"
25245
25246         $LCTL set_param $testname $jobid_var_old
25247         jobid_var_new=$($LCTL get_param -n $testname)
25248         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25249                 error "failed to reset $testname"
25250 }
25251 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25252
25253 test_401e() { # LU-14779
25254         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25255                 error "lctl list_param MGC* failed"
25256         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25257         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25258                 error "lctl get_param lru_size failed"
25259 }
25260 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25261
25262 test_402() {
25263         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25264         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25265                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25266         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25267                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25268                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25269         remote_mds_nodsh && skip "remote MDS with nodsh"
25270
25271         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25272 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25273         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25274         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25275                 echo "Touch failed - OK"
25276 }
25277 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25278
25279 test_403() {
25280         local file1=$DIR/$tfile.1
25281         local file2=$DIR/$tfile.2
25282         local tfile=$TMP/$tfile
25283
25284         rm -f $file1 $file2 $tfile
25285
25286         touch $file1
25287         ln $file1 $file2
25288
25289         # 30 sec OBD_TIMEOUT in ll_getattr()
25290         # right before populating st_nlink
25291         $LCTL set_param fail_loc=0x80001409
25292         stat -c %h $file1 > $tfile &
25293
25294         # create an alias, drop all locks and reclaim the dentry
25295         < $file2
25296         cancel_lru_locks mdc
25297         cancel_lru_locks osc
25298         sysctl -w vm.drop_caches=2
25299
25300         wait
25301
25302         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25303
25304         rm -f $tfile $file1 $file2
25305 }
25306 run_test 403 "i_nlink should not drop to zero due to aliasing"
25307
25308 test_404() { # LU-6601
25309         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25310                 skip "Need server version newer than 2.8.52"
25311         remote_mds_nodsh && skip "remote MDS with nodsh"
25312
25313         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25314                 awk '/osp .*-osc-MDT/ { print $4}')
25315
25316         local osp
25317         for osp in $mosps; do
25318                 echo "Deactivate: " $osp
25319                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25320                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25321                         awk -vp=$osp '$4 == p { print $2 }')
25322                 [ $stat = IN ] || {
25323                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25324                         error "deactivate error"
25325                 }
25326                 echo "Activate: " $osp
25327                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25328                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25329                         awk -vp=$osp '$4 == p { print $2 }')
25330                 [ $stat = UP ] || {
25331                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25332                         error "activate error"
25333                 }
25334         done
25335 }
25336 run_test 404 "validate manual {de}activated works properly for OSPs"
25337
25338 test_405() {
25339         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25340         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25341                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25342                         skip "Layout swap lock is not supported"
25343
25344         check_swap_layouts_support
25345         check_swap_layout_no_dom $DIR
25346
25347         test_mkdir $DIR/$tdir
25348         swap_lock_test -d $DIR/$tdir ||
25349                 error "One layout swap locked test failed"
25350 }
25351 run_test 405 "Various layout swap lock tests"
25352
25353 test_406() {
25354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25355         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25356         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25358         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25359                 skip "Need MDS version at least 2.8.50"
25360
25361         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25362         local test_pool=$TESTNAME
25363
25364         pool_add $test_pool || error "pool_add failed"
25365         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25366                 error "pool_add_targets failed"
25367
25368         save_layout_restore_at_exit $MOUNT
25369
25370         # parent set default stripe count only, child will stripe from both
25371         # parent and fs default
25372         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25373                 error "setstripe $MOUNT failed"
25374         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25375         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25376         for i in $(seq 10); do
25377                 local f=$DIR/$tdir/$tfile.$i
25378                 touch $f || error "touch failed"
25379                 local count=$($LFS getstripe -c $f)
25380                 [ $count -eq $OSTCOUNT ] ||
25381                         error "$f stripe count $count != $OSTCOUNT"
25382                 local offset=$($LFS getstripe -i $f)
25383                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25384                 local size=$($LFS getstripe -S $f)
25385                 [ $size -eq $((def_stripe_size * 2)) ] ||
25386                         error "$f stripe size $size != $((def_stripe_size * 2))"
25387                 local pool=$($LFS getstripe -p $f)
25388                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25389         done
25390
25391         # change fs default striping, delete parent default striping, now child
25392         # will stripe from new fs default striping only
25393         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25394                 error "change $MOUNT default stripe failed"
25395         $LFS setstripe -c 0 $DIR/$tdir ||
25396                 error "delete $tdir default stripe failed"
25397         for i in $(seq 11 20); do
25398                 local f=$DIR/$tdir/$tfile.$i
25399                 touch $f || error "touch $f failed"
25400                 local count=$($LFS getstripe -c $f)
25401                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25402                 local offset=$($LFS getstripe -i $f)
25403                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25404                 local size=$($LFS getstripe -S $f)
25405                 [ $size -eq $def_stripe_size ] ||
25406                         error "$f stripe size $size != $def_stripe_size"
25407                 local pool=$($LFS getstripe -p $f)
25408                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25409         done
25410
25411         unlinkmany $DIR/$tdir/$tfile. 1 20
25412
25413         local f=$DIR/$tdir/$tfile
25414         pool_remove_all_targets $test_pool $f
25415         pool_remove $test_pool $f
25416 }
25417 run_test 406 "DNE support fs default striping"
25418
25419 test_407() {
25420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25421         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25422                 skip "Need MDS version at least 2.8.55"
25423         remote_mds_nodsh && skip "remote MDS with nodsh"
25424
25425         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25426                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25427         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25428                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25429         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25430
25431         #define OBD_FAIL_DT_TXN_STOP    0x2019
25432         for idx in $(seq $MDSCOUNT); do
25433                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25434         done
25435         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25436         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25437                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25438         true
25439 }
25440 run_test 407 "transaction fail should cause operation fail"
25441
25442 test_408() {
25443         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25444
25445         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25446         lctl set_param fail_loc=0x8000040a
25447         # let ll_prepare_partial_page() fail
25448         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25449
25450         rm -f $DIR/$tfile
25451
25452         # create at least 100 unused inodes so that
25453         # shrink_icache_memory(0) should not return 0
25454         touch $DIR/$tfile-{0..100}
25455         rm -f $DIR/$tfile-{0..100}
25456         sync
25457
25458         echo 2 > /proc/sys/vm/drop_caches
25459 }
25460 run_test 408 "drop_caches should not hang due to page leaks"
25461
25462 test_409()
25463 {
25464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25465
25466         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25467         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25468         touch $DIR/$tdir/guard || error "(2) Fail to create"
25469
25470         local PREFIX=$(str_repeat 'A' 128)
25471         echo "Create 1K hard links start at $(date)"
25472         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25473                 error "(3) Fail to hard link"
25474
25475         echo "Links count should be right although linkEA overflow"
25476         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25477         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25478         [ $linkcount -eq 1001 ] ||
25479                 error "(5) Unexpected hard links count: $linkcount"
25480
25481         echo "List all links start at $(date)"
25482         ls -l $DIR/$tdir/foo > /dev/null ||
25483                 error "(6) Fail to list $DIR/$tdir/foo"
25484
25485         echo "Unlink hard links start at $(date)"
25486         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25487                 error "(7) Fail to unlink"
25488         echo "Unlink hard links finished at $(date)"
25489 }
25490 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25491
25492 test_410()
25493 {
25494         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25495                 skip "Need client version at least 2.9.59"
25496         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25497                 skip "Need MODULES build"
25498
25499         # Create a file, and stat it from the kernel
25500         local testfile=$DIR/$tfile
25501         touch $testfile
25502
25503         local run_id=$RANDOM
25504         local my_ino=$(stat --format "%i" $testfile)
25505
25506         # Try to insert the module. This will always fail as the
25507         # module is designed to not be inserted.
25508         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25509             &> /dev/null
25510
25511         # Anything but success is a test failure
25512         dmesg | grep -q \
25513             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25514             error "no inode match"
25515 }
25516 run_test 410 "Test inode number returned from kernel thread"
25517
25518 cleanup_test411_cgroup() {
25519         trap 0
25520         rmdir "$1"
25521 }
25522
25523 test_411() {
25524         local cg_basedir=/sys/fs/cgroup/memory
25525         # LU-9966
25526         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25527                 skip "no setup for cgroup"
25528
25529         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25530                 error "test file creation failed"
25531         cancel_lru_locks osc
25532
25533         # Create a very small memory cgroup to force a slab allocation error
25534         local cgdir=$cg_basedir/osc_slab_alloc
25535         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25536         trap "cleanup_test411_cgroup $cgdir" EXIT
25537         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25538         echo 1M > $cgdir/memory.limit_in_bytes
25539
25540         # Should not LBUG, just be killed by oom-killer
25541         # dd will return 0 even allocation failure in some environment.
25542         # So don't check return value
25543         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25544         cleanup_test411_cgroup $cgdir
25545
25546         return 0
25547 }
25548 run_test 411 "Slab allocation error with cgroup does not LBUG"
25549
25550 test_412() {
25551         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25552         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25553                 skip "Need server version at least 2.10.55"
25554
25555         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25556                 error "mkdir failed"
25557         $LFS getdirstripe $DIR/$tdir
25558         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25559         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25560                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25561         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25562         [ $stripe_count -eq 2 ] ||
25563                 error "expect 2 get $stripe_count"
25564
25565         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25566
25567         local index
25568         local index2
25569
25570         # subdirs should be on the same MDT as parent
25571         for i in $(seq 0 $((MDSCOUNT - 1))); do
25572                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25573                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25574                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25575                 (( index == i )) || error "mdt$i/sub on MDT$index"
25576         done
25577
25578         # stripe offset -1, ditto
25579         for i in {1..10}; do
25580                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25581                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25582                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25583                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25584                 (( index == index2 )) ||
25585                         error "qos$i on MDT$index, sub on MDT$index2"
25586         done
25587
25588         local testdir=$DIR/$tdir/inherit
25589
25590         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25591         # inherit 2 levels
25592         for i in 1 2; do
25593                 testdir=$testdir/s$i
25594                 mkdir $testdir || error "mkdir $testdir failed"
25595                 index=$($LFS getstripe -m $testdir)
25596                 (( index == 1 )) ||
25597                         error "$testdir on MDT$index"
25598         done
25599
25600         # not inherit any more
25601         testdir=$testdir/s3
25602         mkdir $testdir || error "mkdir $testdir failed"
25603         getfattr -d -m dmv $testdir | grep dmv &&
25604                 error "default LMV set on $testdir" || true
25605 }
25606 run_test 412 "mkdir on specific MDTs"
25607
25608 TEST413_COUNT=${TEST413_COUNT:-200}
25609 generate_uneven_mdts() {
25610         local threshold=$1
25611         local lmv_qos_maxage
25612         local lod_qos_maxage
25613         local ffree
25614         local bavail
25615         local max
25616         local min
25617         local max_index
25618         local min_index
25619         local tmp
25620         local i
25621
25622         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25623         $LCTL set_param lmv.*.qos_maxage=1
25624         stack_trap "$LCTL set_param \
25625                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25626         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25627                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25628         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25629                 lod.*.mdt_qos_maxage=1
25630         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25631                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25632
25633         echo
25634         echo "Check for uneven MDTs: "
25635
25636         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25637         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25638         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25639
25640         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25641         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25642         max_index=0
25643         min_index=0
25644         for ((i = 1; i < ${#ffree[@]}; i++)); do
25645                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25646                 if [ $tmp -gt $max ]; then
25647                         max=$tmp
25648                         max_index=$i
25649                 fi
25650                 if [ $tmp -lt $min ]; then
25651                         min=$tmp
25652                         min_index=$i
25653                 fi
25654         done
25655
25656         (( ${ffree[min_index]} > 0 )) ||
25657                 skip "no free files in MDT$min_index"
25658         (( ${ffree[min_index]} < 10000000 )) ||
25659                 skip "too many free files in MDT$min_index"
25660
25661         # Check if we need to generate uneven MDTs
25662         local diff=$(((max - min) * 100 / min))
25663         local testdir=$DIR/$tdir-fillmdt
25664         local start
25665
25666         i=0
25667         while (( diff < threshold )); do
25668                 mkdir -p $testdir
25669                 # generate uneven MDTs, create till $threshold% diff
25670                 echo -n "weight diff=$diff% must be > $threshold% ..."
25671                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25672                 testdir=$DIR/$tdir-fillmdt/$i
25673                 [ -d $testdir ] && continue
25674                 $LFS mkdir -i $min_index $testdir ||
25675                         error "mkdir $testdir failed"
25676                 $LFS setstripe -E 1M -L mdt $testdir ||
25677                         error "setstripe $testdir failed"
25678                 start=$SECONDS
25679                 for ((F=0; F < TEST413_COUNT; F++)); do
25680                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25681                                 /dev/null 2>&1 || error "dd $F failed"
25682                 done
25683                 sync; sleep 1; sync
25684
25685                 # wait for QOS to update
25686                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25687
25688                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25689                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25690                 max=$(((${ffree[max_index]} >> 8) *
25691                         (${bavail[max_index]} * bsize >> 16)))
25692                 min=$(((${ffree[min_index]} >> 8) *
25693                         (${bavail[min_index]} * bsize >> 16)))
25694                 diff=$(((max - min) * 100 / min))
25695                 i=$((i + 1))
25696         done
25697
25698         echo "MDT filesfree available: ${ffree[*]}"
25699         echo "MDT blocks available: ${bavail[*]}"
25700         echo "weight diff=$diff%"
25701 }
25702
25703 test_qos_mkdir() {
25704         local mkdir_cmd=$1
25705         local stripe_count=$2
25706         local mdts=$(comma_list $(mdts_nodes))
25707
25708         local testdir
25709         local lmv_qos_prio_free
25710         local lmv_qos_threshold_rr
25711         local lmv_qos_maxage
25712         local lod_qos_prio_free
25713         local lod_qos_threshold_rr
25714         local lod_qos_maxage
25715         local count
25716         local i
25717
25718         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25719         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25720         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25721                 head -n1)
25722         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25723         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25724         stack_trap "$LCTL set_param \
25725                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25726         stack_trap "$LCTL set_param \
25727                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25728         stack_trap "$LCTL set_param \
25729                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25730
25731         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25732                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25733         lod_qos_prio_free=${lod_qos_prio_free%%%}
25734         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25735                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25736         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25737         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25738                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25739         stack_trap "do_nodes $mdts $LCTL set_param \
25740                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25741         stack_trap "do_nodes $mdts $LCTL set_param \
25742                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25743         stack_trap "do_nodes $mdts $LCTL set_param \
25744                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25745
25746         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25747         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25748
25749         testdir=$DIR/$tdir-s$stripe_count/rr
25750
25751         local stripe_index=$($LFS getstripe -m $testdir)
25752         local test_mkdir_rr=true
25753
25754         getfattr -d -m dmv -e hex $testdir | grep dmv
25755         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25756                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25757                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25758                         test_mkdir_rr=false
25759         fi
25760
25761         echo
25762         $test_mkdir_rr &&
25763                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25764                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25765
25766         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25767         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25768                 eval $mkdir_cmd $testdir/subdir$i ||
25769                         error "$mkdir_cmd subdir$i failed"
25770         done
25771
25772         for (( i = 0; i < $MDSCOUNT; i++ )); do
25773                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25774                 echo "$count directories created on MDT$i"
25775                 if $test_mkdir_rr; then
25776                         (( $count == 100 )) ||
25777                                 error "subdirs are not evenly distributed"
25778                 elif (( $i == $stripe_index )); then
25779                         (( $count == 100 * MDSCOUNT )) ||
25780                                 error "$count subdirs created on MDT$i"
25781                 else
25782                         (( $count == 0 )) ||
25783                                 error "$count subdirs created on MDT$i"
25784                 fi
25785
25786                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25787                         count=$($LFS getdirstripe $testdir/* |
25788                                 grep -c -P "^\s+$i\t")
25789                         echo "$count stripes created on MDT$i"
25790                         # deviation should < 5% of average
25791                         (( $count >= 95 * stripe_count &&
25792                            $count <= 105 * stripe_count)) ||
25793                                 error "stripes are not evenly distributed"
25794                 fi
25795         done
25796
25797         echo
25798         echo "Check for uneven MDTs: "
25799
25800         local ffree
25801         local bavail
25802         local max
25803         local min
25804         local max_index
25805         local min_index
25806         local tmp
25807
25808         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25809         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25810         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25811
25812         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25813         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25814         max_index=0
25815         min_index=0
25816         for ((i = 1; i < ${#ffree[@]}; i++)); do
25817                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25818                 if [ $tmp -gt $max ]; then
25819                         max=$tmp
25820                         max_index=$i
25821                 fi
25822                 if [ $tmp -lt $min ]; then
25823                         min=$tmp
25824                         min_index=$i
25825                 fi
25826         done
25827
25828         (( ${ffree[min_index]} > 0 )) ||
25829                 skip "no free files in MDT$min_index"
25830         (( ${ffree[min_index]} < 10000000 )) ||
25831                 skip "too many free files in MDT$min_index"
25832
25833         echo "MDT filesfree available: ${ffree[*]}"
25834         echo "MDT blocks available: ${bavail[*]}"
25835         echo "weight diff=$(((max - min) * 100 / min))%"
25836         echo
25837         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25838
25839         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25840         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25841         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25842         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25843         # decrease statfs age, so that it can be updated in time
25844         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25845         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25846
25847         sleep 1
25848
25849         testdir=$DIR/$tdir-s$stripe_count/qos
25850         local num=200
25851
25852         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25853         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25854                 eval $mkdir_cmd $testdir/subdir$i ||
25855                         error "$mkdir_cmd subdir$i failed"
25856         done
25857
25858         max=0
25859         for (( i = 0; i < $MDSCOUNT; i++ )); do
25860                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25861                 (( count > max )) && max=$count
25862                 echo "$count directories created on MDT$i"
25863         done
25864
25865         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25866
25867         # D-value should > 10% of averge
25868         (( max - min > num / 10 )) ||
25869                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25870
25871         # ditto for stripes
25872         if (( stripe_count > 1 )); then
25873                 max=0
25874                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25875                         count=$($LFS getdirstripe $testdir/* |
25876                                 grep -c -P "^\s+$i\t")
25877                         (( count > max )) && max=$count
25878                         echo "$count stripes created on MDT$i"
25879                 done
25880
25881                 min=$($LFS getdirstripe $testdir/* |
25882                         grep -c -P "^\s+$min_index\t")
25883                 (( max - min > num * stripe_count / 10 )) ||
25884                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25885         fi
25886 }
25887
25888 most_full_mdt() {
25889         local ffree
25890         local bavail
25891         local bsize
25892         local min
25893         local min_index
25894         local tmp
25895
25896         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25897         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25898         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25899
25900         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25901         min_index=0
25902         for ((i = 1; i < ${#ffree[@]}; i++)); do
25903                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25904                 (( tmp < min )) && min=$tmp && min_index=$i
25905         done
25906
25907         echo -n $min_index
25908 }
25909
25910 test_413a() {
25911         [ $MDSCOUNT -lt 2 ] &&
25912                 skip "We need at least 2 MDTs for this test"
25913
25914         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25915                 skip "Need server version at least 2.12.52"
25916
25917         local stripe_count
25918
25919         generate_uneven_mdts 100
25920         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25921                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25922                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25923                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25924                         error "mkdir failed"
25925                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25926         done
25927 }
25928 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25929
25930 test_413b() {
25931         [ $MDSCOUNT -lt 2 ] &&
25932                 skip "We need at least 2 MDTs for this test"
25933
25934         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25935                 skip "Need server version at least 2.12.52"
25936
25937         local testdir
25938         local stripe_count
25939
25940         generate_uneven_mdts 100
25941         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25942                 testdir=$DIR/$tdir-s$stripe_count
25943                 mkdir $testdir || error "mkdir $testdir failed"
25944                 mkdir $testdir/rr || error "mkdir rr failed"
25945                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25946                         error "mkdir qos failed"
25947                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25948                         $testdir/rr || error "setdirstripe rr failed"
25949                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25950                         error "setdirstripe failed"
25951                 test_qos_mkdir "mkdir" $stripe_count
25952         done
25953 }
25954 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25955
25956 test_413c() {
25957         (( $MDSCOUNT >= 2 )) ||
25958                 skip "We need at least 2 MDTs for this test"
25959
25960         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25961                 skip "Need server version at least 2.14.51"
25962
25963         local testdir
25964         local inherit
25965         local inherit_rr
25966
25967         testdir=$DIR/${tdir}-s1
25968         mkdir $testdir || error "mkdir $testdir failed"
25969         mkdir $testdir/rr || error "mkdir rr failed"
25970         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25971         # default max_inherit is -1, default max_inherit_rr is 0
25972         $LFS setdirstripe -D -c 1 $testdir/rr ||
25973                 error "setdirstripe rr failed"
25974         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25975                 error "setdirstripe qos failed"
25976         test_qos_mkdir "mkdir" 1
25977
25978         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25979         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25980         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25981         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25982         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25983
25984         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25985         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25986         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25987         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25988         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25989         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25990         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25991                 error "level2 shouldn't have default LMV" || true
25992 }
25993 run_test 413c "mkdir with default LMV max inherit rr"
25994
25995 test_413d() {
25996         (( MDSCOUNT >= 2 )) ||
25997                 skip "We need at least 2 MDTs for this test"
25998
25999         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26000                 skip "Need server version at least 2.14.51"
26001
26002         local lmv_qos_threshold_rr
26003
26004         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26005                 head -n1)
26006         stack_trap "$LCTL set_param \
26007                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26008
26009         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26010         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26011         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26012                 error "$tdir shouldn't have default LMV"
26013         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26014                 error "mkdir sub failed"
26015
26016         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26017
26018         (( count == 100 )) || error "$count subdirs on MDT0"
26019 }
26020 run_test 413d "inherit ROOT default LMV"
26021
26022 test_413e() {
26023         (( MDSCOUNT >= 2 )) ||
26024                 skip "We need at least 2 MDTs for this test"
26025         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26026                 skip "Need server version at least 2.14.55"
26027
26028         local testdir=$DIR/$tdir
26029         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26030         local max_inherit
26031         local sub_max_inherit
26032
26033         mkdir -p $testdir || error "failed to create $testdir"
26034
26035         # set default max-inherit to -1 if stripe count is 0 or 1
26036         $LFS setdirstripe -D -c 1 $testdir ||
26037                 error "failed to set default LMV"
26038         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26039         (( max_inherit == -1 )) ||
26040                 error "wrong max_inherit value $max_inherit"
26041
26042         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26043         $LFS setdirstripe -D -c -1 $testdir ||
26044                 error "failed to set default LMV"
26045         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26046         (( max_inherit > 0 )) ||
26047                 error "wrong max_inherit value $max_inherit"
26048
26049         # and the subdir will decrease the max_inherit by 1
26050         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26051         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26052         (( sub_max_inherit == max_inherit - 1)) ||
26053                 error "wrong max-inherit of subdir $sub_max_inherit"
26054
26055         # check specified --max-inherit and warning message
26056         stack_trap "rm -f $tmpfile"
26057         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26058                 error "failed to set default LMV"
26059         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26060         (( max_inherit == -1 )) ||
26061                 error "wrong max_inherit value $max_inherit"
26062
26063         # check the warning messages
26064         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26065                 error "failed to detect warning string"
26066         fi
26067 }
26068 run_test 413e "check default max-inherit value"
26069
26070 test_fs_dmv_inherit()
26071 {
26072         local testdir=$DIR/$tdir
26073
26074         local count
26075         local inherit
26076         local inherit_rr
26077
26078         for i in 1 2 3; do
26079                 mkdir $testdir || error "mkdir $testdir failed"
26080                 count=$($LFS getdirstripe -D -c $testdir)
26081                 (( count == 1 )) ||
26082                         error "$testdir default LMV count mismatch $count != 1"
26083                 inherit=$($LFS getdirstripe -D -X $testdir)
26084                 (( inherit == 3 - i )) ||
26085                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26086                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26087                 (( inherit_rr == 3 - i )) ||
26088                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26089                 testdir=$testdir/sub
26090         done
26091
26092         mkdir $testdir || error "mkdir $testdir failed"
26093         count=$($LFS getdirstripe -D -c $testdir)
26094         (( count == 0 )) ||
26095                 error "$testdir default LMV count not zero: $count"
26096 }
26097
26098 test_413f() {
26099         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26100
26101         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26102                 skip "Need server version at least 2.14.55"
26103
26104         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26105                 error "dump $DIR default LMV failed"
26106         stack_trap "setfattr --restore=$TMP/dmv.ea"
26107
26108         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26109                 error "set $DIR default LMV failed"
26110
26111         test_fs_dmv_inherit
26112 }
26113 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26114
26115 test_413g() {
26116         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26117
26118         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26119         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26120                 error "dump $DIR default LMV failed"
26121         stack_trap "setfattr --restore=$TMP/dmv.ea"
26122
26123         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26124                 error "set $DIR default LMV failed"
26125
26126         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26127                 error "mount $MOUNT2 failed"
26128         stack_trap "umount_client $MOUNT2"
26129
26130         local saved_DIR=$DIR
26131
26132         export DIR=$MOUNT2
26133
26134         stack_trap "export DIR=$saved_DIR"
26135
26136         # first check filesystem-wide default LMV inheritance
26137         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26138
26139         # then check subdirs are spread to all MDTs
26140         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26141
26142         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26143
26144         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26145 }
26146 run_test 413g "enforce ROOT default LMV on subdir mount"
26147
26148 test_413h() {
26149         (( MDSCOUNT >= 2 )) ||
26150                 skip "We need at least 2 MDTs for this test"
26151
26152         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26153                 skip "Need server version at least 2.15.50.6"
26154
26155         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26156
26157         stack_trap "$LCTL set_param \
26158                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26159         $LCTL set_param lmv.*.qos_maxage=1
26160
26161         local depth=5
26162         local rr_depth=4
26163         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26164         local count=$((MDSCOUNT * 20))
26165
26166         generate_uneven_mdts 50
26167
26168         mkdir -p $dir || error "mkdir $dir failed"
26169         stack_trap "rm -rf $dir"
26170         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26171                 --max-inherit-rr=$rr_depth $dir
26172
26173         for ((d=0; d < depth + 2; d++)); do
26174                 log "dir=$dir:"
26175                 for ((sub=0; sub < count; sub++)); do
26176                         mkdir $dir/d$sub
26177                 done
26178                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26179                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26180                 # subdirs within $rr_depth should be created round-robin
26181                 if (( d < rr_depth )); then
26182                         (( ${num[0]} != count )) ||
26183                                 error "all objects created on MDT ${num[1]}"
26184                 fi
26185
26186                 dir=$dir/d0
26187         done
26188 }
26189 run_test 413h "don't stick to parent for round-robin dirs"
26190
26191 test_413z() {
26192         local pids=""
26193         local subdir
26194         local pid
26195
26196         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26197                 unlinkmany $subdir/f. $TEST413_COUNT &
26198                 pids="$pids $!"
26199         done
26200
26201         for pid in $pids; do
26202                 wait $pid
26203         done
26204 }
26205 run_test 413z "413 test cleanup"
26206
26207 test_414() {
26208 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26209         $LCTL set_param fail_loc=0x80000521
26210         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26211         rm -f $DIR/$tfile
26212 }
26213 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26214
26215 test_415() {
26216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26218                 skip "Need server version at least 2.11.52"
26219
26220         # LU-11102
26221         local total
26222         local setattr_pid
26223         local start_time
26224         local end_time
26225         local duration
26226
26227         total=500
26228         # this test may be slow on ZFS
26229         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26230
26231         # though this test is designed for striped directory, let's test normal
26232         # directory too since lock is always saved as CoS lock.
26233         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26234         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26235
26236         (
26237                 while true; do
26238                         touch $DIR/$tdir
26239                 done
26240         ) &
26241         setattr_pid=$!
26242
26243         start_time=$(date +%s)
26244         for i in $(seq $total); do
26245                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26246                         > /dev/null
26247         done
26248         end_time=$(date +%s)
26249         duration=$((end_time - start_time))
26250
26251         kill -9 $setattr_pid
26252
26253         echo "rename $total files took $duration sec"
26254         [ $duration -lt 100 ] || error "rename took $duration sec"
26255 }
26256 run_test 415 "lock revoke is not missing"
26257
26258 test_416() {
26259         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26260                 skip "Need server version at least 2.11.55"
26261
26262         # define OBD_FAIL_OSD_TXN_START    0x19a
26263         do_facet mds1 lctl set_param fail_loc=0x19a
26264
26265         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26266
26267         true
26268 }
26269 run_test 416 "transaction start failure won't cause system hung"
26270
26271 cleanup_417() {
26272         trap 0
26273         do_nodes $(comma_list $(mdts_nodes)) \
26274                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26275         do_nodes $(comma_list $(mdts_nodes)) \
26276                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26277         do_nodes $(comma_list $(mdts_nodes)) \
26278                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26279 }
26280
26281 test_417() {
26282         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26283         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26284                 skip "Need MDS version at least 2.11.56"
26285
26286         trap cleanup_417 RETURN EXIT
26287
26288         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26289         do_nodes $(comma_list $(mdts_nodes)) \
26290                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26291         $LFS migrate -m 0 $DIR/$tdir.1 &&
26292                 error "migrate dir $tdir.1 should fail"
26293
26294         do_nodes $(comma_list $(mdts_nodes)) \
26295                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26296         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26297                 error "create remote dir $tdir.2 should fail"
26298
26299         do_nodes $(comma_list $(mdts_nodes)) \
26300                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26301         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26302                 error "create striped dir $tdir.3 should fail"
26303         true
26304 }
26305 run_test 417 "disable remote dir, striped dir and dir migration"
26306
26307 # Checks that the outputs of df [-i] and lfs df [-i] match
26308 #
26309 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26310 check_lfs_df() {
26311         local dir=$2
26312         local inodes
26313         local df_out
26314         local lfs_df_out
26315         local count
26316         local passed=false
26317
26318         # blocks or inodes
26319         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26320
26321         for count in {1..100}; do
26322                 do_nodes "$CLIENTS" \
26323                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26324                 sync; sleep 0.2
26325
26326                 # read the lines of interest
26327                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26328                         error "df $inodes $dir | tail -n +2 failed"
26329                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26330                         error "lfs df $inodes $dir | grep summary: failed"
26331
26332                 # skip first substrings of each output as they are different
26333                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26334                 # compare the two outputs
26335                 passed=true
26336                 #  skip "available" on MDT until LU-13997 is fixed.
26337                 #for i in {1..5}; do
26338                 for i in 1 2 4 5; do
26339                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26340                 done
26341                 $passed && break
26342         done
26343
26344         if ! $passed; then
26345                 df -P $inodes $dir
26346                 echo
26347                 lfs df $inodes $dir
26348                 error "df and lfs df $1 output mismatch: "      \
26349                       "df ${inodes}: ${df_out[*]}, "            \
26350                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26351         fi
26352 }
26353
26354 test_418() {
26355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26356
26357         local dir=$DIR/$tdir
26358         local numfiles=$((RANDOM % 4096 + 2))
26359         local numblocks=$((RANDOM % 256 + 1))
26360
26361         wait_delete_completed
26362         test_mkdir $dir
26363
26364         # check block output
26365         check_lfs_df blocks $dir
26366         # check inode output
26367         check_lfs_df inodes $dir
26368
26369         # create a single file and retest
26370         echo "Creating a single file and testing"
26371         createmany -o $dir/$tfile- 1 &>/dev/null ||
26372                 error "creating 1 file in $dir failed"
26373         check_lfs_df blocks $dir
26374         check_lfs_df inodes $dir
26375
26376         # create a random number of files
26377         echo "Creating $((numfiles - 1)) files and testing"
26378         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26379                 error "creating $((numfiles - 1)) files in $dir failed"
26380
26381         # write a random number of blocks to the first test file
26382         echo "Writing $numblocks 4K blocks and testing"
26383         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26384                 count=$numblocks &>/dev/null ||
26385                 error "dd to $dir/${tfile}-0 failed"
26386
26387         # retest
26388         check_lfs_df blocks $dir
26389         check_lfs_df inodes $dir
26390
26391         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26392                 error "unlinking $numfiles files in $dir failed"
26393 }
26394 run_test 418 "df and lfs df outputs match"
26395
26396 test_419()
26397 {
26398         local dir=$DIR/$tdir
26399
26400         mkdir -p $dir
26401         touch $dir/file
26402
26403         cancel_lru_locks mdc
26404
26405         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26406         $LCTL set_param fail_loc=0x1410
26407         cat $dir/file
26408         $LCTL set_param fail_loc=0
26409         rm -rf $dir
26410 }
26411 run_test 419 "Verify open file by name doesn't crash kernel"
26412
26413 test_420()
26414 {
26415         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26416                 skip "Need MDS version at least 2.12.53"
26417
26418         local SAVE_UMASK=$(umask)
26419         local dir=$DIR/$tdir
26420         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26421
26422         mkdir -p $dir
26423         umask 0000
26424         mkdir -m03777 $dir/testdir
26425         ls -dn $dir/testdir
26426         # Need to remove trailing '.' when SELinux is enabled
26427         local dirperms=$(ls -dn $dir/testdir |
26428                          awk '{ sub(/\.$/, "", $1); print $1}')
26429         [ $dirperms == "drwxrwsrwt" ] ||
26430                 error "incorrect perms on $dir/testdir"
26431
26432         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26433                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26434         ls -n $dir/testdir/testfile
26435         local fileperms=$(ls -n $dir/testdir/testfile |
26436                           awk '{ sub(/\.$/, "", $1); print $1}')
26437         [ $fileperms == "-rwxr-xr-x" ] ||
26438                 error "incorrect perms on $dir/testdir/testfile"
26439
26440         umask $SAVE_UMASK
26441 }
26442 run_test 420 "clear SGID bit on non-directories for non-members"
26443
26444 test_421a() {
26445         local cnt
26446         local fid1
26447         local fid2
26448
26449         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26450                 skip "Need MDS version at least 2.12.54"
26451
26452         test_mkdir $DIR/$tdir
26453         createmany -o $DIR/$tdir/f 3
26454         cnt=$(ls -1 $DIR/$tdir | wc -l)
26455         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26456
26457         fid1=$(lfs path2fid $DIR/$tdir/f1)
26458         fid2=$(lfs path2fid $DIR/$tdir/f2)
26459         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26460
26461         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26462         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26463
26464         cnt=$(ls -1 $DIR/$tdir | wc -l)
26465         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26466
26467         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26468         createmany -o $DIR/$tdir/f 3
26469         cnt=$(ls -1 $DIR/$tdir | wc -l)
26470         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26471
26472         fid1=$(lfs path2fid $DIR/$tdir/f1)
26473         fid2=$(lfs path2fid $DIR/$tdir/f2)
26474         echo "remove using fsname $FSNAME"
26475         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26476
26477         cnt=$(ls -1 $DIR/$tdir | wc -l)
26478         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26479 }
26480 run_test 421a "simple rm by fid"
26481
26482 test_421b() {
26483         local cnt
26484         local FID1
26485         local FID2
26486
26487         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26488                 skip "Need MDS version at least 2.12.54"
26489
26490         test_mkdir $DIR/$tdir
26491         createmany -o $DIR/$tdir/f 3
26492         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26493         MULTIPID=$!
26494
26495         FID1=$(lfs path2fid $DIR/$tdir/f1)
26496         FID2=$(lfs path2fid $DIR/$tdir/f2)
26497         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26498
26499         kill -USR1 $MULTIPID
26500         wait
26501
26502         cnt=$(ls $DIR/$tdir | wc -l)
26503         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26504 }
26505 run_test 421b "rm by fid on open file"
26506
26507 test_421c() {
26508         local cnt
26509         local FIDS
26510
26511         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26512                 skip "Need MDS version at least 2.12.54"
26513
26514         test_mkdir $DIR/$tdir
26515         createmany -o $DIR/$tdir/f 3
26516         touch $DIR/$tdir/$tfile
26517         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26518         cnt=$(ls -1 $DIR/$tdir | wc -l)
26519         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26520
26521         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26522         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26523
26524         cnt=$(ls $DIR/$tdir | wc -l)
26525         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26526 }
26527 run_test 421c "rm by fid against hardlinked files"
26528
26529 test_421d() {
26530         local cnt
26531         local FIDS
26532
26533         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26534                 skip "Need MDS version at least 2.12.54"
26535
26536         test_mkdir $DIR/$tdir
26537         createmany -o $DIR/$tdir/f 4097
26538         cnt=$(ls -1 $DIR/$tdir | wc -l)
26539         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26540
26541         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26542         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26543
26544         cnt=$(ls $DIR/$tdir | wc -l)
26545         rm -rf $DIR/$tdir
26546         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26547 }
26548 run_test 421d "rmfid en masse"
26549
26550 test_421e() {
26551         local cnt
26552         local FID
26553
26554         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26555         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26556                 skip "Need MDS version at least 2.12.54"
26557
26558         mkdir -p $DIR/$tdir
26559         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26560         createmany -o $DIR/$tdir/striped_dir/f 512
26561         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26562         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26563
26564         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26565                 sed "s/[/][^:]*://g")
26566         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26567
26568         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26569         rm -rf $DIR/$tdir
26570         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26571 }
26572 run_test 421e "rmfid in DNE"
26573
26574 test_421f() {
26575         local cnt
26576         local FID
26577
26578         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26579                 skip "Need MDS version at least 2.12.54"
26580
26581         test_mkdir $DIR/$tdir
26582         touch $DIR/$tdir/f
26583         cnt=$(ls -1 $DIR/$tdir | wc -l)
26584         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26585
26586         FID=$(lfs path2fid $DIR/$tdir/f)
26587         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26588         # rmfid should fail
26589         cnt=$(ls -1 $DIR/$tdir | wc -l)
26590         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26591
26592         chmod a+rw $DIR/$tdir
26593         ls -la $DIR/$tdir
26594         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26595         # rmfid should fail
26596         cnt=$(ls -1 $DIR/$tdir | wc -l)
26597         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26598
26599         rm -f $DIR/$tdir/f
26600         $RUNAS touch $DIR/$tdir/f
26601         FID=$(lfs path2fid $DIR/$tdir/f)
26602         echo "rmfid as root"
26603         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26604         cnt=$(ls -1 $DIR/$tdir | wc -l)
26605         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26606
26607         rm -f $DIR/$tdir/f
26608         $RUNAS touch $DIR/$tdir/f
26609         cnt=$(ls -1 $DIR/$tdir | wc -l)
26610         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26611         FID=$(lfs path2fid $DIR/$tdir/f)
26612         # rmfid w/o user_fid2path mount option should fail
26613         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26614         cnt=$(ls -1 $DIR/$tdir | wc -l)
26615         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26616
26617         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26618         stack_trap "rmdir $tmpdir"
26619         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26620                 error "failed to mount client'"
26621         stack_trap "umount_client $tmpdir"
26622
26623         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26624         # rmfid should succeed
26625         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26626         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26627
26628         # rmfid shouldn't allow to remove files due to dir's permission
26629         chmod a+rwx $tmpdir/$tdir
26630         touch $tmpdir/$tdir/f
26631         ls -la $tmpdir/$tdir
26632         FID=$(lfs path2fid $tmpdir/$tdir/f)
26633         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26634         return 0
26635 }
26636 run_test 421f "rmfid checks permissions"
26637
26638 test_421g() {
26639         local cnt
26640         local FIDS
26641
26642         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26643         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26644                 skip "Need MDS version at least 2.12.54"
26645
26646         mkdir -p $DIR/$tdir
26647         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26648         createmany -o $DIR/$tdir/striped_dir/f 512
26649         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26650         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26651
26652         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26653                 sed "s/[/][^:]*://g")
26654
26655         rm -f $DIR/$tdir/striped_dir/f1*
26656         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26657         removed=$((512 - cnt))
26658
26659         # few files have been just removed, so we expect
26660         # rmfid to fail on their fids
26661         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26662         [ $removed != $errors ] && error "$errors != $removed"
26663
26664         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26665         rm -rf $DIR/$tdir
26666         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26667 }
26668 run_test 421g "rmfid to return errors properly"
26669
26670 test_422() {
26671         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26672         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26673         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26674         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26675         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26676
26677         local amc=$(at_max_get client)
26678         local amo=$(at_max_get mds1)
26679         local timeout=`lctl get_param -n timeout`
26680
26681         at_max_set 0 client
26682         at_max_set 0 mds1
26683
26684 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26685         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26686                         fail_val=$(((2*timeout + 10)*1000))
26687         touch $DIR/$tdir/d3/file &
26688         sleep 2
26689 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26690         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26691                         fail_val=$((2*timeout + 5))
26692         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26693         local pid=$!
26694         sleep 1
26695         kill -9 $pid
26696         sleep $((2 * timeout))
26697         echo kill $pid
26698         kill -9 $pid
26699         lctl mark touch
26700         touch $DIR/$tdir/d2/file3
26701         touch $DIR/$tdir/d2/file4
26702         touch $DIR/$tdir/d2/file5
26703
26704         wait
26705         at_max_set $amc client
26706         at_max_set $amo mds1
26707
26708         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26709         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26710                 error "Watchdog is always throttled"
26711 }
26712 run_test 422 "kill a process with RPC in progress"
26713
26714 stat_test() {
26715     df -h $MOUNT &
26716     df -h $MOUNT &
26717     df -h $MOUNT &
26718     df -h $MOUNT &
26719     df -h $MOUNT &
26720     df -h $MOUNT &
26721 }
26722
26723 test_423() {
26724     local _stats
26725     # ensure statfs cache is expired
26726     sleep 2;
26727
26728     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26729     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26730
26731     return 0
26732 }
26733 run_test 423 "statfs should return a right data"
26734
26735 test_424() {
26736 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26737         $LCTL set_param fail_loc=0x80000522
26738         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26739         rm -f $DIR/$tfile
26740 }
26741 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26742
26743 test_425() {
26744         test_mkdir -c -1 $DIR/$tdir
26745         $LFS setstripe -c -1 $DIR/$tdir
26746
26747         lru_resize_disable "" 100
26748         stack_trap "lru_resize_enable" EXIT
26749
26750         sleep 5
26751
26752         for i in $(seq $((MDSCOUNT * 125))); do
26753                 local t=$DIR/$tdir/$tfile_$i
26754
26755                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26756                         error_noexit "Create file $t"
26757         done
26758         stack_trap "rm -rf $DIR/$tdir" EXIT
26759
26760         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26761                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26762                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26763
26764                 [ $lock_count -le $lru_size ] ||
26765                         error "osc lock count $lock_count > lru size $lru_size"
26766         done
26767
26768         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26769                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26770                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26771
26772                 [ $lock_count -le $lru_size ] ||
26773                         error "mdc lock count $lock_count > lru size $lru_size"
26774         done
26775 }
26776 run_test 425 "lock count should not exceed lru size"
26777
26778 test_426() {
26779         splice-test -r $DIR/$tfile
26780         splice-test -rd $DIR/$tfile
26781         splice-test $DIR/$tfile
26782         splice-test -d $DIR/$tfile
26783 }
26784 run_test 426 "splice test on Lustre"
26785
26786 test_427() {
26787         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26788         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26789                 skip "Need MDS version at least 2.12.4"
26790         local log
26791
26792         mkdir $DIR/$tdir
26793         mkdir $DIR/$tdir/1
26794         mkdir $DIR/$tdir/2
26795         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26796         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26797
26798         $LFS getdirstripe $DIR/$tdir/1/dir
26799
26800         #first setfattr for creating updatelog
26801         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26802
26803 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26804         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26805         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26806         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26807
26808         sleep 2
26809         fail mds2
26810         wait_recovery_complete mds2 $((2*TIMEOUT))
26811
26812         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26813         echo $log | grep "get update log failed" &&
26814                 error "update log corruption is detected" || true
26815 }
26816 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26817
26818 test_428() {
26819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26820         local cache_limit=$CACHE_MAX
26821
26822         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26823         $LCTL set_param -n llite.*.max_cached_mb=64
26824
26825         mkdir $DIR/$tdir
26826         $LFS setstripe -c 1 $DIR/$tdir
26827         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26828         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26829         #test write
26830         for f in $(seq 4); do
26831                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26832         done
26833         wait
26834
26835         cancel_lru_locks osc
26836         # Test read
26837         for f in $(seq 4); do
26838                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26839         done
26840         wait
26841 }
26842 run_test 428 "large block size IO should not hang"
26843
26844 test_429() { # LU-7915 / LU-10948
26845         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26846         local testfile=$DIR/$tfile
26847         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26848         local new_flag=1
26849         local first_rpc
26850         local second_rpc
26851         local third_rpc
26852
26853         $LCTL get_param $ll_opencache_threshold_count ||
26854                 skip "client does not have opencache parameter"
26855
26856         set_opencache $new_flag
26857         stack_trap "restore_opencache"
26858         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26859                 error "enable opencache failed"
26860         touch $testfile
26861         # drop MDC DLM locks
26862         cancel_lru_locks mdc
26863         # clear MDC RPC stats counters
26864         $LCTL set_param $mdc_rpcstats=clear
26865
26866         # According to the current implementation, we need to run 3 times
26867         # open & close file to verify if opencache is enabled correctly.
26868         # 1st, RPCs are sent for lookup/open and open handle is released on
26869         #      close finally.
26870         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26871         #      so open handle won't be released thereafter.
26872         # 3rd, No RPC is sent out.
26873         $MULTIOP $testfile oc || error "multiop failed"
26874         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26875         echo "1st: $first_rpc RPCs in flight"
26876
26877         $MULTIOP $testfile oc || error "multiop failed"
26878         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26879         echo "2nd: $second_rpc RPCs in flight"
26880
26881         $MULTIOP $testfile oc || error "multiop failed"
26882         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26883         echo "3rd: $third_rpc RPCs in flight"
26884
26885         #verify no MDC RPC is sent
26886         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26887 }
26888 run_test 429 "verify if opencache flag on client side does work"
26889
26890 lseek_test_430() {
26891         local offset
26892         local file=$1
26893
26894         # data at [200K, 400K)
26895         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26896                 error "256K->512K dd fails"
26897         # data at [2M, 3M)
26898         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26899                 error "2M->3M dd fails"
26900         # data at [4M, 5M)
26901         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26902                 error "4M->5M dd fails"
26903         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26904         # start at first component hole #1
26905         printf "Seeking hole from 1000 ... "
26906         offset=$(lseek_test -l 1000 $file)
26907         echo $offset
26908         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26909         printf "Seeking data from 1000 ... "
26910         offset=$(lseek_test -d 1000 $file)
26911         echo $offset
26912         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26913
26914         # start at first component data block
26915         printf "Seeking hole from 300000 ... "
26916         offset=$(lseek_test -l 300000 $file)
26917         echo $offset
26918         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26919         printf "Seeking data from 300000 ... "
26920         offset=$(lseek_test -d 300000 $file)
26921         echo $offset
26922         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26923
26924         # start at the first component but beyond end of object size
26925         printf "Seeking hole from 1000000 ... "
26926         offset=$(lseek_test -l 1000000 $file)
26927         echo $offset
26928         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26929         printf "Seeking data from 1000000 ... "
26930         offset=$(lseek_test -d 1000000 $file)
26931         echo $offset
26932         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26933
26934         # start at second component stripe 2 (empty file)
26935         printf "Seeking hole from 1500000 ... "
26936         offset=$(lseek_test -l 1500000 $file)
26937         echo $offset
26938         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26939         printf "Seeking data from 1500000 ... "
26940         offset=$(lseek_test -d 1500000 $file)
26941         echo $offset
26942         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26943
26944         # start at second component stripe 1 (all data)
26945         printf "Seeking hole from 3000000 ... "
26946         offset=$(lseek_test -l 3000000 $file)
26947         echo $offset
26948         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26949         printf "Seeking data from 3000000 ... "
26950         offset=$(lseek_test -d 3000000 $file)
26951         echo $offset
26952         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26953
26954         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26955                 error "2nd dd fails"
26956         echo "Add data block at 640K...1280K"
26957
26958         # start at before new data block, in hole
26959         printf "Seeking hole from 600000 ... "
26960         offset=$(lseek_test -l 600000 $file)
26961         echo $offset
26962         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26963         printf "Seeking data from 600000 ... "
26964         offset=$(lseek_test -d 600000 $file)
26965         echo $offset
26966         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26967
26968         # start at the first component new data block
26969         printf "Seeking hole from 1000000 ... "
26970         offset=$(lseek_test -l 1000000 $file)
26971         echo $offset
26972         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26973         printf "Seeking data from 1000000 ... "
26974         offset=$(lseek_test -d 1000000 $file)
26975         echo $offset
26976         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26977
26978         # start at second component stripe 2, new data
26979         printf "Seeking hole from 1200000 ... "
26980         offset=$(lseek_test -l 1200000 $file)
26981         echo $offset
26982         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26983         printf "Seeking data from 1200000 ... "
26984         offset=$(lseek_test -d 1200000 $file)
26985         echo $offset
26986         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26987
26988         # start beyond file end
26989         printf "Using offset > filesize ... "
26990         lseek_test -l 4000000 $file && error "lseek should fail"
26991         printf "Using offset > filesize ... "
26992         lseek_test -d 4000000 $file && error "lseek should fail"
26993
26994         printf "Done\n\n"
26995 }
26996
26997 test_430a() {
26998         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26999                 skip "MDT does not support SEEK_HOLE"
27000
27001         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27002                 skip "OST does not support SEEK_HOLE"
27003
27004         local file=$DIR/$tdir/$tfile
27005
27006         mkdir -p $DIR/$tdir
27007
27008         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27009         # OST stripe #1 will have continuous data at [1M, 3M)
27010         # OST stripe #2 is empty
27011         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27012         lseek_test_430 $file
27013         rm $file
27014         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27015         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27016         lseek_test_430 $file
27017         rm $file
27018         $LFS setstripe -c2 -S 512K $file
27019         echo "Two stripes, stripe size 512K"
27020         lseek_test_430 $file
27021         rm $file
27022         # FLR with stale mirror
27023         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27024                        -N -c2 -S 1M $file
27025         echo "Mirrored file:"
27026         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27027         echo "Plain 2 stripes 1M"
27028         lseek_test_430 $file
27029         rm $file
27030 }
27031 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27032
27033 test_430b() {
27034         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27035                 skip "OST does not support SEEK_HOLE"
27036
27037         local offset
27038         local file=$DIR/$tdir/$tfile
27039
27040         mkdir -p $DIR/$tdir
27041         # Empty layout lseek should fail
27042         $MCREATE $file
27043         # seek from 0
27044         printf "Seeking hole from 0 ... "
27045         lseek_test -l 0 $file && error "lseek should fail"
27046         printf "Seeking data from 0 ... "
27047         lseek_test -d 0 $file && error "lseek should fail"
27048         rm $file
27049
27050         # 1M-hole file
27051         $LFS setstripe -E 1M -c2 -E eof $file
27052         $TRUNCATE $file 1048576
27053         printf "Seeking hole from 1000000 ... "
27054         offset=$(lseek_test -l 1000000 $file)
27055         echo $offset
27056         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27057         printf "Seeking data from 1000000 ... "
27058         lseek_test -d 1000000 $file && error "lseek should fail"
27059         rm $file
27060
27061         # full component followed by non-inited one
27062         $LFS setstripe -E 1M -c2 -E eof $file
27063         dd if=/dev/urandom of=$file bs=1M count=1
27064         printf "Seeking hole from 1000000 ... "
27065         offset=$(lseek_test -l 1000000 $file)
27066         echo $offset
27067         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27068         printf "Seeking hole from 1048576 ... "
27069         lseek_test -l 1048576 $file && error "lseek should fail"
27070         # init second component and truncate back
27071         echo "123" >> $file
27072         $TRUNCATE $file 1048576
27073         printf "Seeking hole from 1000000 ... "
27074         offset=$(lseek_test -l 1000000 $file)
27075         echo $offset
27076         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27077         printf "Seeking hole from 1048576 ... "
27078         lseek_test -l 1048576 $file && error "lseek should fail"
27079         # boundary checks for big values
27080         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27081         offset=$(lseek_test -d 0 $file.10g)
27082         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27083         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27084         offset=$(lseek_test -d 0 $file.100g)
27085         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27086         return 0
27087 }
27088 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27089
27090 test_430c() {
27091         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27092                 skip "OST does not support SEEK_HOLE"
27093
27094         local file=$DIR/$tdir/$tfile
27095         local start
27096
27097         mkdir -p $DIR/$tdir
27098         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27099
27100         # cp version 8.33+ prefers lseek over fiemap
27101         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27102                 start=$SECONDS
27103                 time cp $file /dev/null
27104                 (( SECONDS - start < 5 )) ||
27105                         error "cp: too long runtime $((SECONDS - start))"
27106
27107         fi
27108         # tar version 1.29+ supports SEEK_HOLE/DATA
27109         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27110                 start=$SECONDS
27111                 time tar cS $file - | cat > /dev/null
27112                 (( SECONDS - start < 5 )) ||
27113                         error "tar: too long runtime $((SECONDS - start))"
27114         fi
27115 }
27116 run_test 430c "lseek: external tools check"
27117
27118 test_431() { # LU-14187
27119         local file=$DIR/$tdir/$tfile
27120
27121         mkdir -p $DIR/$tdir
27122         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27123         dd if=/dev/urandom of=$file bs=4k count=1
27124         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27125         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27126         #define OBD_FAIL_OST_RESTART_IO 0x251
27127         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27128         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27129         cp $file $file.0
27130         cancel_lru_locks
27131         sync_all_data
27132         echo 3 > /proc/sys/vm/drop_caches
27133         diff  $file $file.0 || error "data diff"
27134 }
27135 run_test 431 "Restart transaction for IO"
27136
27137 cleanup_test_432() {
27138         do_facet mgs $LCTL nodemap_activate 0
27139         wait_nm_sync active
27140 }
27141
27142 test_432() {
27143         local tmpdir=$TMP/dir432
27144
27145         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27146                 skip "Need MDS version at least 2.14.52"
27147
27148         stack_trap cleanup_test_432 EXIT
27149         mkdir $DIR/$tdir
27150         mkdir $tmpdir
27151
27152         do_facet mgs $LCTL nodemap_activate 1
27153         wait_nm_sync active
27154         do_facet mgs $LCTL nodemap_modify --name default \
27155                 --property admin --value 1
27156         do_facet mgs $LCTL nodemap_modify --name default \
27157                 --property trusted --value 1
27158         cancel_lru_locks mdc
27159         wait_nm_sync default admin_nodemap
27160         wait_nm_sync default trusted_nodemap
27161
27162         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27163                grep -ci "Operation not permitted") -ne 0 ]; then
27164                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27165         fi
27166 }
27167 run_test 432 "mv dir from outside Lustre"
27168
27169 test_433() {
27170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27171
27172         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27173                 skip "inode cache not supported"
27174
27175         $LCTL set_param llite.*.inode_cache=0
27176         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27177
27178         local count=256
27179         local before
27180         local after
27181
27182         cancel_lru_locks mdc
27183         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27184         createmany -m $DIR/$tdir/f $count
27185         createmany -d $DIR/$tdir/d $count
27186         ls -l $DIR/$tdir > /dev/null
27187         stack_trap "rm -rf $DIR/$tdir"
27188
27189         before=$(num_objects)
27190         cancel_lru_locks mdc
27191         after=$(num_objects)
27192
27193         # sometimes even @before is less than 2 * count
27194         while (( before - after < count )); do
27195                 sleep 1
27196                 after=$(num_objects)
27197                 wait=$((wait + 1))
27198                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27199                 if (( wait > 60 )); then
27200                         error "inode slab grew from $before to $after"
27201                 fi
27202         done
27203
27204         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27205 }
27206 run_test 433 "ldlm lock cancel releases dentries and inodes"
27207
27208 prep_801() {
27209         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27210         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27211                 skip "Need server version at least 2.9.55"
27212
27213         start_full_debug_logging
27214 }
27215
27216 post_801() {
27217         stop_full_debug_logging
27218 }
27219
27220 barrier_stat() {
27221         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27222                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27223                            awk '/The barrier for/ { print $7 }')
27224                 echo $st
27225         else
27226                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27227                 echo \'$st\'
27228         fi
27229 }
27230
27231 barrier_expired() {
27232         local expired
27233
27234         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27235                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27236                           awk '/will be expired/ { print $7 }')
27237         else
27238                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27239         fi
27240
27241         echo $expired
27242 }
27243
27244 test_801a() {
27245         prep_801
27246
27247         echo "Start barrier_freeze at: $(date)"
27248         #define OBD_FAIL_BARRIER_DELAY          0x2202
27249         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27250         # Do not reduce barrier time - See LU-11873
27251         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27252
27253         sleep 2
27254         local b_status=$(barrier_stat)
27255         echo "Got barrier status at: $(date)"
27256         [ "$b_status" = "'freezing_p1'" ] ||
27257                 error "(1) unexpected barrier status $b_status"
27258
27259         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27260         wait
27261         b_status=$(barrier_stat)
27262         [ "$b_status" = "'frozen'" ] ||
27263                 error "(2) unexpected barrier status $b_status"
27264
27265         local expired=$(barrier_expired)
27266         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27267         sleep $((expired + 3))
27268
27269         b_status=$(barrier_stat)
27270         [ "$b_status" = "'expired'" ] ||
27271                 error "(3) unexpected barrier status $b_status"
27272
27273         # Do not reduce barrier time - See LU-11873
27274         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27275                 error "(4) fail to freeze barrier"
27276
27277         b_status=$(barrier_stat)
27278         [ "$b_status" = "'frozen'" ] ||
27279                 error "(5) unexpected barrier status $b_status"
27280
27281         echo "Start barrier_thaw at: $(date)"
27282         #define OBD_FAIL_BARRIER_DELAY          0x2202
27283         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27284         do_facet mgs $LCTL barrier_thaw $FSNAME &
27285
27286         sleep 2
27287         b_status=$(barrier_stat)
27288         echo "Got barrier status at: $(date)"
27289         [ "$b_status" = "'thawing'" ] ||
27290                 error "(6) unexpected barrier status $b_status"
27291
27292         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27293         wait
27294         b_status=$(barrier_stat)
27295         [ "$b_status" = "'thawed'" ] ||
27296                 error "(7) unexpected barrier status $b_status"
27297
27298         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27300         do_facet mgs $LCTL barrier_freeze $FSNAME
27301
27302         b_status=$(barrier_stat)
27303         [ "$b_status" = "'failed'" ] ||
27304                 error "(8) unexpected barrier status $b_status"
27305
27306         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27307         do_facet mgs $LCTL barrier_thaw $FSNAME
27308
27309         post_801
27310 }
27311 run_test 801a "write barrier user interfaces and stat machine"
27312
27313 test_801b() {
27314         prep_801
27315
27316         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27317         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27318         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27319         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27320         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27321
27322         cancel_lru_locks mdc
27323
27324         # 180 seconds should be long enough
27325         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27326
27327         local b_status=$(barrier_stat)
27328         [ "$b_status" = "'frozen'" ] ||
27329                 error "(6) unexpected barrier status $b_status"
27330
27331         mkdir $DIR/$tdir/d0/d10 &
27332         mkdir_pid=$!
27333
27334         touch $DIR/$tdir/d1/f13 &
27335         touch_pid=$!
27336
27337         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27338         ln_pid=$!
27339
27340         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27341         mv_pid=$!
27342
27343         rm -f $DIR/$tdir/d4/f12 &
27344         rm_pid=$!
27345
27346         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27347
27348         # To guarantee taht the 'stat' is not blocked
27349         b_status=$(barrier_stat)
27350         [ "$b_status" = "'frozen'" ] ||
27351                 error "(8) unexpected barrier status $b_status"
27352
27353         # let above commands to run at background
27354         sleep 5
27355
27356         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27357         ps -p $touch_pid || error "(10) touch should be blocked"
27358         ps -p $ln_pid || error "(11) link should be blocked"
27359         ps -p $mv_pid || error "(12) rename should be blocked"
27360         ps -p $rm_pid || error "(13) unlink should be blocked"
27361
27362         b_status=$(barrier_stat)
27363         [ "$b_status" = "'frozen'" ] ||
27364                 error "(14) unexpected barrier status $b_status"
27365
27366         do_facet mgs $LCTL barrier_thaw $FSNAME
27367         b_status=$(barrier_stat)
27368         [ "$b_status" = "'thawed'" ] ||
27369                 error "(15) unexpected barrier status $b_status"
27370
27371         wait $mkdir_pid || error "(16) mkdir should succeed"
27372         wait $touch_pid || error "(17) touch should succeed"
27373         wait $ln_pid || error "(18) link should succeed"
27374         wait $mv_pid || error "(19) rename should succeed"
27375         wait $rm_pid || error "(20) unlink should succeed"
27376
27377         post_801
27378 }
27379 run_test 801b "modification will be blocked by write barrier"
27380
27381 test_801c() {
27382         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27383
27384         prep_801
27385
27386         stop mds2 || error "(1) Fail to stop mds2"
27387
27388         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27389
27390         local b_status=$(barrier_stat)
27391         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27392                 do_facet mgs $LCTL barrier_thaw $FSNAME
27393                 error "(2) unexpected barrier status $b_status"
27394         }
27395
27396         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27397                 error "(3) Fail to rescan barrier bitmap"
27398
27399         # Do not reduce barrier time - See LU-11873
27400         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27401
27402         b_status=$(barrier_stat)
27403         [ "$b_status" = "'frozen'" ] ||
27404                 error "(4) unexpected barrier status $b_status"
27405
27406         do_facet mgs $LCTL barrier_thaw $FSNAME
27407         b_status=$(barrier_stat)
27408         [ "$b_status" = "'thawed'" ] ||
27409                 error "(5) unexpected barrier status $b_status"
27410
27411         local devname=$(mdsdevname 2)
27412
27413         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27414
27415         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27416                 error "(7) Fail to rescan barrier bitmap"
27417
27418         post_801
27419 }
27420 run_test 801c "rescan barrier bitmap"
27421
27422 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27423 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27424 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27425 saved_MOUNT_OPTS=$MOUNT_OPTS
27426
27427 cleanup_802a() {
27428         trap 0
27429
27430         stopall
27431         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27432         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27433         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27434         MOUNT_OPTS=$saved_MOUNT_OPTS
27435         setupall
27436 }
27437
27438 test_802a() {
27439         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27440         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27441         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27442                 skip "Need server version at least 2.9.55"
27443
27444         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27445
27446         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27447
27448         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27449                 error "(2) Fail to copy"
27450
27451         trap cleanup_802a EXIT
27452
27453         # sync by force before remount as readonly
27454         sync; sync_all_data; sleep 3; sync_all_data
27455
27456         stopall
27457
27458         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27459         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27460         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27461
27462         echo "Mount the server as read only"
27463         setupall server_only || error "(3) Fail to start servers"
27464
27465         echo "Mount client without ro should fail"
27466         mount_client $MOUNT &&
27467                 error "(4) Mount client without 'ro' should fail"
27468
27469         echo "Mount client with ro should succeed"
27470         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27471         mount_client $MOUNT ||
27472                 error "(5) Mount client with 'ro' should succeed"
27473
27474         echo "Modify should be refused"
27475         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27476
27477         echo "Read should be allowed"
27478         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27479                 error "(7) Read should succeed under ro mode"
27480
27481         cleanup_802a
27482 }
27483 run_test 802a "simulate readonly device"
27484
27485 test_802b() {
27486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27487         remote_mds_nodsh && skip "remote MDS with nodsh"
27488
27489         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27490                 skip "readonly option not available"
27491
27492         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27493
27494         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27495                 error "(2) Fail to copy"
27496
27497         # write back all cached data before setting MDT to readonly
27498         cancel_lru_locks
27499         sync_all_data
27500
27501         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27502         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27503
27504         echo "Modify should be refused"
27505         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27506
27507         echo "Read should be allowed"
27508         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27509                 error "(7) Read should succeed under ro mode"
27510
27511         # disable readonly
27512         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27513 }
27514 run_test 802b "be able to set MDTs to readonly"
27515
27516 test_803a() {
27517         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27518         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27519                 skip "MDS needs to be newer than 2.10.54"
27520
27521         mkdir_on_mdt0 $DIR/$tdir
27522         # Create some objects on all MDTs to trigger related logs objects
27523         for idx in $(seq $MDSCOUNT); do
27524                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27525                         $DIR/$tdir/dir${idx} ||
27526                         error "Fail to create $DIR/$tdir/dir${idx}"
27527         done
27528
27529         sync; sleep 3
27530         wait_delete_completed # ensure old test cleanups are finished
27531         echo "before create:"
27532         $LFS df -i $MOUNT
27533         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27534
27535         for i in {1..10}; do
27536                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27537                         error "Fail to create $DIR/$tdir/foo$i"
27538         done
27539
27540         sync; sleep 3
27541         echo "after create:"
27542         $LFS df -i $MOUNT
27543         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27544
27545         # allow for an llog to be cleaned up during the test
27546         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27547                 error "before ($before_used) + 10 > after ($after_used)"
27548
27549         for i in {1..10}; do
27550                 rm -rf $DIR/$tdir/foo$i ||
27551                         error "Fail to remove $DIR/$tdir/foo$i"
27552         done
27553
27554         sleep 3 # avoid MDT return cached statfs
27555         wait_delete_completed
27556         echo "after unlink:"
27557         $LFS df -i $MOUNT
27558         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27559
27560         # allow for an llog to be created during the test
27561         [ $after_used -le $((before_used + 1)) ] ||
27562                 error "after ($after_used) > before ($before_used) + 1"
27563 }
27564 run_test 803a "verify agent object for remote object"
27565
27566 test_803b() {
27567         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27568         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27569                 skip "MDS needs to be newer than 2.13.56"
27570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27571
27572         for i in $(seq 0 $((MDSCOUNT - 1))); do
27573                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27574         done
27575
27576         local before=0
27577         local after=0
27578
27579         local tmp
27580
27581         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27582         for i in $(seq 0 $((MDSCOUNT - 1))); do
27583                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27584                         awk '/getattr/ { print $2 }')
27585                 before=$((before + tmp))
27586         done
27587         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27588         for i in $(seq 0 $((MDSCOUNT - 1))); do
27589                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27590                         awk '/getattr/ { print $2 }')
27591                 after=$((after + tmp))
27592         done
27593
27594         [ $before -eq $after ] || error "getattr count $before != $after"
27595 }
27596 run_test 803b "remote object can getattr from cache"
27597
27598 test_804() {
27599         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27600         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27601                 skip "MDS needs to be newer than 2.10.54"
27602         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27603
27604         mkdir -p $DIR/$tdir
27605         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27606                 error "Fail to create $DIR/$tdir/dir0"
27607
27608         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27609         local dev=$(mdsdevname 2)
27610
27611         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27612                 grep ${fid} || error "NOT found agent entry for dir0"
27613
27614         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27615                 error "Fail to create $DIR/$tdir/dir1"
27616
27617         touch $DIR/$tdir/dir1/foo0 ||
27618                 error "Fail to create $DIR/$tdir/dir1/foo0"
27619         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27620         local rc=0
27621
27622         for idx in $(seq $MDSCOUNT); do
27623                 dev=$(mdsdevname $idx)
27624                 do_facet mds${idx} \
27625                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27626                         grep ${fid} && rc=$idx
27627         done
27628
27629         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27630                 error "Fail to rename foo0 to foo1"
27631         if [ $rc -eq 0 ]; then
27632                 for idx in $(seq $MDSCOUNT); do
27633                         dev=$(mdsdevname $idx)
27634                         do_facet mds${idx} \
27635                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27636                         grep ${fid} && rc=$idx
27637                 done
27638         fi
27639
27640         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27641                 error "Fail to rename foo1 to foo2"
27642         if [ $rc -eq 0 ]; then
27643                 for idx in $(seq $MDSCOUNT); do
27644                         dev=$(mdsdevname $idx)
27645                         do_facet mds${idx} \
27646                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27647                         grep ${fid} && rc=$idx
27648                 done
27649         fi
27650
27651         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27652
27653         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27654                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27655         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27656                 error "Fail to rename foo2 to foo0"
27657         unlink $DIR/$tdir/dir1/foo0 ||
27658                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27659         rm -rf $DIR/$tdir/dir0 ||
27660                 error "Fail to rm $DIR/$tdir/dir0"
27661
27662         for idx in $(seq $MDSCOUNT); do
27663                 rc=0
27664
27665                 stop mds${idx}
27666                 dev=$(mdsdevname $idx)
27667                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27668                         rc=$?
27669                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27670                         error "mount mds$idx failed"
27671                 df $MOUNT > /dev/null 2>&1
27672
27673                 # e2fsck should not return error
27674                 [ $rc -eq 0 ] ||
27675                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27676         done
27677 }
27678 run_test 804 "verify agent entry for remote entry"
27679
27680 cleanup_805() {
27681         do_facet $SINGLEMDS zfs set quota=$old $fsset
27682         unlinkmany $DIR/$tdir/f- 1000000
27683         trap 0
27684 }
27685
27686 test_805() {
27687         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27688         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27689         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27690                 skip "netfree not implemented before 0.7"
27691         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27692                 skip "Need MDS version at least 2.10.57"
27693
27694         local fsset
27695         local freekb
27696         local usedkb
27697         local old
27698         local quota
27699         local pref="osd-zfs.$FSNAME-MDT0000."
27700
27701         # limit available space on MDS dataset to meet nospace issue
27702         # quickly. then ZFS 0.7.2 can use reserved space if asked
27703         # properly (using netfree flag in osd_declare_destroy()
27704         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27705         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27706                 gawk '{print $3}')
27707         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27708         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27709         let "usedkb=usedkb-freekb"
27710         let "freekb=freekb/2"
27711         if let "freekb > 5000"; then
27712                 let "freekb=5000"
27713         fi
27714         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27715         trap cleanup_805 EXIT
27716         mkdir_on_mdt0 $DIR/$tdir
27717         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27718                 error "Can't set PFL layout"
27719         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27720         rm -rf $DIR/$tdir || error "not able to remove"
27721         do_facet $SINGLEMDS zfs set quota=$old $fsset
27722         trap 0
27723 }
27724 run_test 805 "ZFS can remove from full fs"
27725
27726 # Size-on-MDS test
27727 check_lsom_data()
27728 {
27729         local file=$1
27730         local expect=$(stat -c %s $file)
27731
27732         check_lsom_size $1 $expect
27733
27734         local blocks=$($LFS getsom -b $file)
27735         expect=$(stat -c %b $file)
27736         [[ $blocks == $expect ]] ||
27737                 error "$file expected blocks: $expect, got: $blocks"
27738 }
27739
27740 check_lsom_size()
27741 {
27742         local size
27743         local expect=$2
27744
27745         cancel_lru_locks mdc
27746
27747         size=$($LFS getsom -s $1)
27748         [[ $size == $expect ]] ||
27749                 error "$file expected size: $expect, got: $size"
27750 }
27751
27752 test_806() {
27753         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27754                 skip "Need MDS version at least 2.11.52"
27755
27756         local bs=1048576
27757
27758         touch $DIR/$tfile || error "touch $tfile failed"
27759
27760         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27761         save_lustre_params client "llite.*.xattr_cache" > $save
27762         lctl set_param llite.*.xattr_cache=0
27763         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27764
27765         # single-threaded write
27766         echo "Test SOM for single-threaded write"
27767         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27768                 error "write $tfile failed"
27769         check_lsom_size $DIR/$tfile $bs
27770
27771         local num=32
27772         local size=$(($num * $bs))
27773         local offset=0
27774         local i
27775
27776         echo "Test SOM for single client multi-threaded($num) write"
27777         $TRUNCATE $DIR/$tfile 0
27778         for ((i = 0; i < $num; i++)); do
27779                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27780                 local pids[$i]=$!
27781                 offset=$((offset + $bs))
27782         done
27783         for (( i=0; i < $num; i++ )); do
27784                 wait ${pids[$i]}
27785         done
27786         check_lsom_size $DIR/$tfile $size
27787
27788         $TRUNCATE $DIR/$tfile 0
27789         for ((i = 0; i < $num; i++)); do
27790                 offset=$((offset - $bs))
27791                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27792                 local pids[$i]=$!
27793         done
27794         for (( i=0; i < $num; i++ )); do
27795                 wait ${pids[$i]}
27796         done
27797         check_lsom_size $DIR/$tfile $size
27798
27799         # multi-client writes
27800         num=$(get_node_count ${CLIENTS//,/ })
27801         size=$(($num * $bs))
27802         offset=0
27803         i=0
27804
27805         echo "Test SOM for multi-client ($num) writes"
27806         $TRUNCATE $DIR/$tfile 0
27807         for client in ${CLIENTS//,/ }; do
27808                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27809                 local pids[$i]=$!
27810                 i=$((i + 1))
27811                 offset=$((offset + $bs))
27812         done
27813         for (( i=0; i < $num; i++ )); do
27814                 wait ${pids[$i]}
27815         done
27816         check_lsom_size $DIR/$tfile $offset
27817
27818         i=0
27819         $TRUNCATE $DIR/$tfile 0
27820         for client in ${CLIENTS//,/ }; do
27821                 offset=$((offset - $bs))
27822                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27823                 local pids[$i]=$!
27824                 i=$((i + 1))
27825         done
27826         for (( i=0; i < $num; i++ )); do
27827                 wait ${pids[$i]}
27828         done
27829         check_lsom_size $DIR/$tfile $size
27830
27831         # verify truncate
27832         echo "Test SOM for truncate"
27833         $TRUNCATE $DIR/$tfile 1048576
27834         check_lsom_size $DIR/$tfile 1048576
27835         $TRUNCATE $DIR/$tfile 1234
27836         check_lsom_size $DIR/$tfile 1234
27837
27838         # verify SOM blocks count
27839         echo "Verify SOM block count"
27840         $TRUNCATE $DIR/$tfile 0
27841         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27842                 error "failed to write file $tfile"
27843         check_lsom_data $DIR/$tfile
27844 }
27845 run_test 806 "Verify Lazy Size on MDS"
27846
27847 test_807() {
27848         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27850                 skip "Need MDS version at least 2.11.52"
27851
27852         # Registration step
27853         changelog_register || error "changelog_register failed"
27854         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27855         changelog_users $SINGLEMDS | grep -q $cl_user ||
27856                 error "User $cl_user not found in changelog_users"
27857
27858         rm -rf $DIR/$tdir || error "rm $tdir failed"
27859         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27860         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27861         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27862         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27863                 error "truncate $tdir/trunc failed"
27864
27865         local bs=1048576
27866         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27867                 error "write $tfile failed"
27868
27869         # multi-client wirtes
27870         local num=$(get_node_count ${CLIENTS//,/ })
27871         local offset=0
27872         local i=0
27873
27874         echo "Test SOM for multi-client ($num) writes"
27875         touch $DIR/$tfile || error "touch $tfile failed"
27876         $TRUNCATE $DIR/$tfile 0
27877         for client in ${CLIENTS//,/ }; do
27878                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27879                 local pids[$i]=$!
27880                 i=$((i + 1))
27881                 offset=$((offset + $bs))
27882         done
27883         for (( i=0; i < $num; i++ )); do
27884                 wait ${pids[$i]}
27885         done
27886
27887         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27888         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27889         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27890         check_lsom_data $DIR/$tdir/trunc
27891         check_lsom_data $DIR/$tdir/single_dd
27892         check_lsom_data $DIR/$tfile
27893
27894         rm -rf $DIR/$tdir
27895         # Deregistration step
27896         changelog_deregister || error "changelog_deregister failed"
27897 }
27898 run_test 807 "verify LSOM syncing tool"
27899
27900 check_som_nologged()
27901 {
27902         local lines=$($LFS changelog $FSNAME-MDT0000 |
27903                 grep 'x=trusted.som' | wc -l)
27904         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27905 }
27906
27907 test_808() {
27908         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27909                 skip "Need MDS version at least 2.11.55"
27910
27911         # Registration step
27912         changelog_register || error "changelog_register failed"
27913
27914         touch $DIR/$tfile || error "touch $tfile failed"
27915         check_som_nologged
27916
27917         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27918                 error "write $tfile failed"
27919         check_som_nologged
27920
27921         $TRUNCATE $DIR/$tfile 1234
27922         check_som_nologged
27923
27924         $TRUNCATE $DIR/$tfile 1048576
27925         check_som_nologged
27926
27927         # Deregistration step
27928         changelog_deregister || error "changelog_deregister failed"
27929 }
27930 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27931
27932 check_som_nodata()
27933 {
27934         $LFS getsom $1
27935         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27936 }
27937
27938 test_809() {
27939         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27940                 skip "Need MDS version at least 2.11.56"
27941
27942         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27943                 error "failed to create DoM-only file $DIR/$tfile"
27944         touch $DIR/$tfile || error "touch $tfile failed"
27945         check_som_nodata $DIR/$tfile
27946
27947         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27948                 error "write $tfile failed"
27949         check_som_nodata $DIR/$tfile
27950
27951         $TRUNCATE $DIR/$tfile 1234
27952         check_som_nodata $DIR/$tfile
27953
27954         $TRUNCATE $DIR/$tfile 4097
27955         check_som_nodata $DIR/$file
27956 }
27957 run_test 809 "Verify no SOM xattr store for DoM-only files"
27958
27959 test_810() {
27960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27961         $GSS && skip_env "could not run with gss"
27962         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27963                 skip "OST < 2.12.58 doesn't align checksum"
27964
27965         set_checksums 1
27966         stack_trap "set_checksums $ORIG_CSUM" EXIT
27967         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27968
27969         local csum
27970         local before
27971         local after
27972         for csum in $CKSUM_TYPES; do
27973                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27974                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27975                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27976                         eval set -- $i
27977                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27978                         before=$(md5sum $DIR/$tfile)
27979                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27980                         after=$(md5sum $DIR/$tfile)
27981                         [ "$before" == "$after" ] ||
27982                                 error "$csum: $before != $after bs=$1 seek=$2"
27983                 done
27984         done
27985 }
27986 run_test 810 "partial page writes on ZFS (LU-11663)"
27987
27988 test_812a() {
27989         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27990                 skip "OST < 2.12.51 doesn't support this fail_loc"
27991
27992         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27993         # ensure ost1 is connected
27994         stat $DIR/$tfile >/dev/null || error "can't stat"
27995         wait_osc_import_state client ost1 FULL
27996         # no locks, no reqs to let the connection idle
27997         cancel_lru_locks osc
27998
27999         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28000 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28001         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28002         wait_osc_import_state client ost1 CONNECTING
28003         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28004
28005         stat $DIR/$tfile >/dev/null || error "can't stat file"
28006 }
28007 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28008
28009 test_812b() { # LU-12378
28010         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28011                 skip "OST < 2.12.51 doesn't support this fail_loc"
28012
28013         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28014         # ensure ost1 is connected
28015         stat $DIR/$tfile >/dev/null || error "can't stat"
28016         wait_osc_import_state client ost1 FULL
28017         # no locks, no reqs to let the connection idle
28018         cancel_lru_locks osc
28019
28020         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28021 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28022         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28023         wait_osc_import_state client ost1 CONNECTING
28024         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28025
28026         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28027         wait_osc_import_state client ost1 IDLE
28028 }
28029 run_test 812b "do not drop no resend request for idle connect"
28030
28031 test_812c() {
28032         local old
28033
28034         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28035
28036         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28037         $LFS getstripe $DIR/$tfile
28038         $LCTL set_param osc.*.idle_timeout=10
28039         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28040         # ensure ost1 is connected
28041         stat $DIR/$tfile >/dev/null || error "can't stat"
28042         wait_osc_import_state client ost1 FULL
28043         # no locks, no reqs to let the connection idle
28044         cancel_lru_locks osc
28045
28046 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28047         $LCTL set_param fail_loc=0x80000533
28048         sleep 15
28049         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28050 }
28051 run_test 812c "idle import vs lock enqueue race"
28052
28053 test_813() {
28054         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28055         [ -z "$file_heat_sav" ] && skip "no file heat support"
28056
28057         local readsample
28058         local writesample
28059         local readbyte
28060         local writebyte
28061         local readsample1
28062         local writesample1
28063         local readbyte1
28064         local writebyte1
28065
28066         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28067         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28068
28069         $LCTL set_param -n llite.*.file_heat=1
28070         echo "Turn on file heat"
28071         echo "Period second: $period_second, Decay percentage: $decay_pct"
28072
28073         echo "QQQQ" > $DIR/$tfile
28074         echo "QQQQ" > $DIR/$tfile
28075         echo "QQQQ" > $DIR/$tfile
28076         cat $DIR/$tfile > /dev/null
28077         cat $DIR/$tfile > /dev/null
28078         cat $DIR/$tfile > /dev/null
28079         cat $DIR/$tfile > /dev/null
28080
28081         local out=$($LFS heat_get $DIR/$tfile)
28082
28083         $LFS heat_get $DIR/$tfile
28084         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28085         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28086         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28087         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28088
28089         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28090         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28091         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28092         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28093
28094         sleep $((period_second + 3))
28095         echo "Sleep $((period_second + 3)) seconds..."
28096         # The recursion formula to calculate the heat of the file f is as
28097         # follow:
28098         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28099         # Where Hi is the heat value in the period between time points i*I and
28100         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28101         # to the weight of Ci.
28102         out=$($LFS heat_get $DIR/$tfile)
28103         $LFS heat_get $DIR/$tfile
28104         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28105         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28106         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28107         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28108
28109         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28110                 error "read sample ($readsample) is wrong"
28111         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28112                 error "write sample ($writesample) is wrong"
28113         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28114                 error "read bytes ($readbyte) is wrong"
28115         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28116                 error "write bytes ($writebyte) is wrong"
28117
28118         echo "QQQQ" > $DIR/$tfile
28119         echo "QQQQ" > $DIR/$tfile
28120         echo "QQQQ" > $DIR/$tfile
28121         cat $DIR/$tfile > /dev/null
28122         cat $DIR/$tfile > /dev/null
28123         cat $DIR/$tfile > /dev/null
28124         cat $DIR/$tfile > /dev/null
28125
28126         sleep $((period_second + 3))
28127         echo "Sleep $((period_second + 3)) seconds..."
28128
28129         out=$($LFS heat_get $DIR/$tfile)
28130         $LFS heat_get $DIR/$tfile
28131         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28132         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28133         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28134         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28135
28136         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28137                 4 * $decay_pct) / 100") -eq 1 ] ||
28138                 error "read sample ($readsample1) is wrong"
28139         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28140                 3 * $decay_pct) / 100") -eq 1 ] ||
28141                 error "write sample ($writesample1) is wrong"
28142         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28143                 20 * $decay_pct) / 100") -eq 1 ] ||
28144                 error "read bytes ($readbyte1) is wrong"
28145         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28146                 15 * $decay_pct) / 100") -eq 1 ] ||
28147                 error "write bytes ($writebyte1) is wrong"
28148
28149         echo "Turn off file heat for the file $DIR/$tfile"
28150         $LFS heat_set -o $DIR/$tfile
28151
28152         echo "QQQQ" > $DIR/$tfile
28153         echo "QQQQ" > $DIR/$tfile
28154         echo "QQQQ" > $DIR/$tfile
28155         cat $DIR/$tfile > /dev/null
28156         cat $DIR/$tfile > /dev/null
28157         cat $DIR/$tfile > /dev/null
28158         cat $DIR/$tfile > /dev/null
28159
28160         out=$($LFS heat_get $DIR/$tfile)
28161         $LFS heat_get $DIR/$tfile
28162         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28163         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28164         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28165         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28166
28167         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28168         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28169         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28170         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28171
28172         echo "Trun on file heat for the file $DIR/$tfile"
28173         $LFS heat_set -O $DIR/$tfile
28174
28175         echo "QQQQ" > $DIR/$tfile
28176         echo "QQQQ" > $DIR/$tfile
28177         echo "QQQQ" > $DIR/$tfile
28178         cat $DIR/$tfile > /dev/null
28179         cat $DIR/$tfile > /dev/null
28180         cat $DIR/$tfile > /dev/null
28181         cat $DIR/$tfile > /dev/null
28182
28183         out=$($LFS heat_get $DIR/$tfile)
28184         $LFS heat_get $DIR/$tfile
28185         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28186         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28187         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28188         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28189
28190         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28191         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28192         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28193         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28194
28195         $LFS heat_set -c $DIR/$tfile
28196         $LCTL set_param -n llite.*.file_heat=0
28197         echo "Turn off file heat support for the Lustre filesystem"
28198
28199         echo "QQQQ" > $DIR/$tfile
28200         echo "QQQQ" > $DIR/$tfile
28201         echo "QQQQ" > $DIR/$tfile
28202         cat $DIR/$tfile > /dev/null
28203         cat $DIR/$tfile > /dev/null
28204         cat $DIR/$tfile > /dev/null
28205         cat $DIR/$tfile > /dev/null
28206
28207         out=$($LFS heat_get $DIR/$tfile)
28208         $LFS heat_get $DIR/$tfile
28209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28213
28214         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28215         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28216         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28217         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28218
28219         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28220         rm -f $DIR/$tfile
28221 }
28222 run_test 813 "File heat verfication"
28223
28224 test_814()
28225 {
28226         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28227         echo -n y >> $DIR/$tfile
28228         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28229         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28230 }
28231 run_test 814 "sparse cp works as expected (LU-12361)"
28232
28233 test_815()
28234 {
28235         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28236         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28237 }
28238 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28239
28240 test_816() {
28241         local ost1_imp=$(get_osc_import_name client ost1)
28242         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28243                          cut -d'.' -f2)
28244
28245         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28246         # ensure ost1 is connected
28247
28248         stat $DIR/$tfile >/dev/null || error "can't stat"
28249         wait_osc_import_state client ost1 FULL
28250         # no locks, no reqs to let the connection idle
28251         cancel_lru_locks osc
28252         lru_resize_disable osc
28253         local before
28254         local now
28255         before=$($LCTL get_param -n \
28256                  ldlm.namespaces.$imp_name.lru_size)
28257
28258         wait_osc_import_state client ost1 IDLE
28259         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28260         now=$($LCTL get_param -n \
28261               ldlm.namespaces.$imp_name.lru_size)
28262         [ $before == $now ] || error "lru_size changed $before != $now"
28263 }
28264 run_test 816 "do not reset lru_resize on idle reconnect"
28265
28266 cleanup_817() {
28267         umount $tmpdir
28268         exportfs -u localhost:$DIR/nfsexp
28269         rm -rf $DIR/nfsexp
28270 }
28271
28272 test_817() {
28273         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28274
28275         mkdir -p $DIR/nfsexp
28276         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28277                 error "failed to export nfs"
28278
28279         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28280         stack_trap cleanup_817 EXIT
28281
28282         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28283                 error "failed to mount nfs to $tmpdir"
28284
28285         cp /bin/true $tmpdir
28286         $DIR/nfsexp/true || error "failed to execute 'true' command"
28287 }
28288 run_test 817 "nfsd won't cache write lock for exec file"
28289
28290 test_818() {
28291         test_mkdir -i0 -c1 $DIR/$tdir
28292         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28293         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28294         stop $SINGLEMDS
28295
28296         # restore osp-syn threads
28297         stack_trap "fail $SINGLEMDS"
28298
28299         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28300         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28301         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28302                 error "start $SINGLEMDS failed"
28303         rm -rf $DIR/$tdir
28304
28305         local testid=$(echo $TESTNAME | tr '_' ' ')
28306
28307         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28308                 grep "run LFSCK" || error "run LFSCK is not suggested"
28309 }
28310 run_test 818 "unlink with failed llog"
28311
28312 test_819a() {
28313         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28314         cancel_lru_locks osc
28315         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28316         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28317         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28318         rm -f $TDIR/$tfile
28319 }
28320 run_test 819a "too big niobuf in read"
28321
28322 test_819b() {
28323         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28324         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28326         cancel_lru_locks osc
28327         sleep 1
28328         rm -f $TDIR/$tfile
28329 }
28330 run_test 819b "too big niobuf in write"
28331
28332
28333 function test_820_start_ost() {
28334         sleep 5
28335
28336         for num in $(seq $OSTCOUNT); do
28337                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28338         done
28339 }
28340
28341 test_820() {
28342         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28343
28344         mkdir $DIR/$tdir
28345         umount_client $MOUNT || error "umount failed"
28346         for num in $(seq $OSTCOUNT); do
28347                 stop ost$num
28348         done
28349
28350         # mount client with no active OSTs
28351         # so that the client can't initialize max LOV EA size
28352         # from OSC notifications
28353         mount_client $MOUNT || error "mount failed"
28354         # delay OST starting to keep this 0 max EA size for a while
28355         test_820_start_ost &
28356
28357         # create a directory on MDS2
28358         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28359                 error "Failed to create directory"
28360         # open intent should update default EA size
28361         # see mdc_update_max_ea_from_body()
28362         # notice this is the very first RPC to MDS2
28363         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28364         ret=$?
28365         echo $out
28366         # With SSK, this situation can lead to -EPERM being returned.
28367         # In that case, simply retry.
28368         if [ $ret -ne 0 ] && $SHARED_KEY; then
28369                 if echo "$out" | grep -q "not permitted"; then
28370                         cp /etc/services $DIR/$tdir/mds2
28371                         ret=$?
28372                 fi
28373         fi
28374         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28375 }
28376 run_test 820 "update max EA from open intent"
28377
28378 test_823() {
28379         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28380         local OST_MAX_PRECREATE=20000
28381
28382         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28383                 skip "Need MDS version at least 2.14.56"
28384
28385         save_lustre_params mds1 \
28386                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28387         do_facet $SINGLEMDS "$LCTL set_param -n \
28388                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28389         do_facet $SINGLEMDS "$LCTL set_param -n \
28390                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28391
28392         stack_trap "restore_lustre_params < $p; rm $p"
28393
28394         do_facet $SINGLEMDS "$LCTL set_param -n \
28395                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28396
28397         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28398                       osp.$FSNAME-OST0000*MDT0000.create_count")
28399         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28400                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28401         local expect_count=$(((($max/2)/256) * 256))
28402
28403         log "setting create_count to 100200:"
28404         log " -result- count: $count with max: $max, expecting: $expect_count"
28405
28406         [[ $count -eq expect_count ]] ||
28407                 error "Create count not set to max precreate."
28408 }
28409 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28410
28411 test_831() {
28412         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28413                 skip "Need MDS version 2.14.56"
28414
28415         local sync_changes=$(do_facet $SINGLEMDS \
28416                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28417
28418         [ "$sync_changes" -gt 100 ] &&
28419                 skip "Sync changes $sync_changes > 100 already"
28420
28421         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28422
28423         $LFS mkdir -i 0 $DIR/$tdir
28424         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28425
28426         save_lustre_params mds1 \
28427                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28428         save_lustre_params mds1 \
28429                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28430
28431         do_facet mds1 "$LCTL set_param -n \
28432                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28433                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28434         stack_trap "restore_lustre_params < $p" EXIT
28435
28436         createmany -o $DIR/$tdir/f- 1000
28437         unlinkmany $DIR/$tdir/f- 1000 &
28438         local UNLINK_PID=$!
28439
28440         while sleep 1; do
28441                 sync_changes=$(do_facet mds1 \
28442                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28443                 # the check in the code is racy, fail the test
28444                 # if the value above the limit by 10.
28445                 [ $sync_changes -gt 110 ] && {
28446                         kill -2 $UNLINK_PID
28447                         wait
28448                         error "osp changes throttling failed, $sync_changes>110"
28449                 }
28450                 kill -0 $UNLINK_PID 2> /dev/null || break
28451         done
28452         wait
28453 }
28454 run_test 831 "throttling unlink/setattr queuing on OSP"
28455
28456 #
28457 # tests that do cleanup/setup should be run at the end
28458 #
28459
28460 test_900() {
28461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28462         local ls
28463
28464         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28465         $LCTL set_param fail_loc=0x903
28466
28467         cancel_lru_locks MGC
28468
28469         FAIL_ON_ERROR=true cleanup
28470         FAIL_ON_ERROR=true setup
28471 }
28472 run_test 900 "umount should not race with any mgc requeue thread"
28473
28474 # LUS-6253/LU-11185
28475 test_901() {
28476         local old
28477         local count
28478         local oldc
28479         local newc
28480         local olds
28481         local news
28482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28483
28484         # some get_param have a bug to handle dot in param name
28485         cancel_lru_locks MGC
28486         old=$(mount -t lustre | wc -l)
28487         # 1 config+sptlrpc
28488         # 2 params
28489         # 3 nodemap
28490         # 4 IR
28491         old=$((old * 4))
28492         oldc=0
28493         count=0
28494         while [ $old -ne $oldc ]; do
28495                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28496                 sleep 1
28497                 ((count++))
28498                 if [ $count -ge $TIMEOUT ]; then
28499                         error "too large timeout"
28500                 fi
28501         done
28502         umount_client $MOUNT || error "umount failed"
28503         mount_client $MOUNT || error "mount failed"
28504         cancel_lru_locks MGC
28505         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28506
28507         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28508
28509         return 0
28510 }
28511 run_test 901 "don't leak a mgc lock on client umount"
28512
28513 # LU-13377
28514 test_902() {
28515         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28516                 skip "client does not have LU-13377 fix"
28517         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28518         $LCTL set_param fail_loc=0x1415
28519         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28520         cancel_lru_locks osc
28521         rm -f $DIR/$tfile
28522 }
28523 run_test 902 "test short write doesn't hang lustre"
28524
28525 # LU-14711
28526 test_903() {
28527         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28528         echo "blah" > $DIR/${tfile}-2
28529         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28530         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28531         $LCTL set_param fail_loc=0x417 fail_val=20
28532
28533         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28534         sleep 1 # To start the destroy
28535         wait_destroy_complete 150 || error "Destroy taking too long"
28536         cat $DIR/$tfile > /dev/null || error "Evicted"
28537 }
28538 run_test 903 "Test long page discard does not cause evictions"
28539
28540 test_904() {
28541         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28542         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28543                 grep -q project || skip "skip project quota not supported"
28544
28545         local testfile="$DIR/$tdir/$tfile"
28546         local xattr="trusted.projid"
28547         local projid
28548         local mdts=$(comma_list $(mdts_nodes))
28549         local saved=$(do_facet mds1 $LCTL get_param -n \
28550                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28551
28552         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28553         stack_trap "do_nodes $mdts $LCTL set_param \
28554                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28555
28556         mkdir -p $DIR/$tdir
28557         touch $testfile
28558         #hide projid xattr on server
28559         $LFS project -p 1 $testfile ||
28560                 error "set $testfile project id failed"
28561         getfattr -m - $testfile | grep $xattr &&
28562                 error "do not show trusted.projid when disabled on server"
28563         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28564         #should be hidden when projid is 0
28565         $LFS project -p 0 $testfile ||
28566                 error "set $testfile project id failed"
28567         getfattr -m - $testfile | grep $xattr &&
28568                 error "do not show trusted.projid with project ID 0"
28569
28570         #still can getxattr explicitly
28571         projid=$(getfattr -n $xattr $testfile |
28572                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28573         [ $projid == "0" ] ||
28574                 error "projid expected 0 not $projid"
28575
28576         #set the projid via setxattr
28577         setfattr -n $xattr -v "1000" $testfile ||
28578                 error "setattr failed with $?"
28579         projid=($($LFS project $testfile))
28580         [ ${projid[0]} == "1000" ] ||
28581                 error "projid expected 1000 not $projid"
28582
28583         #check the new projid via getxattr
28584         $LFS project -p 1001 $testfile ||
28585                 error "set $testfile project id failed"
28586         getfattr -m - $testfile | grep $xattr ||
28587                 error "should show trusted.projid when project ID != 0"
28588         projid=$(getfattr -n $xattr $testfile |
28589                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28590         [ $projid == "1001" ] ||
28591                 error "projid expected 1001 not $projid"
28592
28593         #try to set invalid projid
28594         setfattr -n $xattr -v "4294967295" $testfile &&
28595                 error "set invalid projid should fail"
28596
28597         #remove the xattr means setting projid to 0
28598         setfattr -x $xattr $testfile ||
28599                 error "setfattr failed with $?"
28600         projid=($($LFS project $testfile))
28601         [ ${projid[0]} == "0" ] ||
28602                 error "projid expected 0 not $projid"
28603
28604         #should be hidden when parent has inherit flag and same projid
28605         $LFS project -srp 1002 $DIR/$tdir ||
28606                 error "set $tdir project id failed"
28607         getfattr -m - $testfile | grep $xattr &&
28608                 error "do not show trusted.projid with inherit flag"
28609
28610         #still can getxattr explicitly
28611         projid=$(getfattr -n $xattr $testfile |
28612                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28613         [ $projid == "1002" ] ||
28614                 error "projid expected 1002 not $projid"
28615 }
28616 run_test 904 "virtual project ID xattr"
28617
28618 # LU-8582
28619 test_905() {
28620         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28621                 skip "lustre < 2.8.54 does not support ladvise"
28622
28623         remote_ost_nodsh && skip "remote OST with nodsh"
28624         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28625
28626         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28627
28628         #define OBD_FAIL_OST_OPCODE 0x253
28629         # OST_LADVISE = 21
28630         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28631         $LFS ladvise -a willread $DIR/$tfile &&
28632                 error "unexpected success of ladvise with fault injection"
28633         $LFS ladvise -a willread $DIR/$tfile |&
28634                 grep -q "Operation not supported"
28635         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28636 }
28637 run_test 905 "bad or new opcode should not stuck client"
28638
28639 complete $SECONDS
28640 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28641 check_and_cleanup_lustre
28642 if [ "$I_MOUNTED" != "yes" ]; then
28643         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28644 fi
28645 exit_status