Whamcloud - gitweb
LU-14139 statahead: add total hit/miss count stats
[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                          awk '/statahead.wrong:/ { print $NF }')
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                          awk '/statahead.wrong:/ { print $NF }')
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 > $delta*105 && $delta_sa > $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 $NF }')
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 $NF }')
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         $LCTL set_param llite.*.statahead_stats=0 ||
13192                 error "clear statahead_stats failed"
13193         swrong=$(lctl get_param -n llite.*.statahead_stats |
13194                  awk '/statahead.wrong:/ { print $NF }')
13195         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13196         # wait for statahead thread finished to update hit/miss stats.
13197         sleep 1
13198         $LCTL get_param -n llite.*.statahead_stats
13199         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13200                  awk '/statahead.wrong:/ { print $NF }')
13201         (( $swrong == $ewrong )) ||
13202                 log "statahead was stopped, maybe too many locks held!"
13203 }
13204 run_test 123d "Statahead on striped directories works correctly"
13205
13206 test_124a() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13209                 skip_env "no lru resize on server"
13210
13211         local NR=2000
13212
13213         test_mkdir $DIR/$tdir
13214
13215         log "create $NR files at $DIR/$tdir"
13216         createmany -o $DIR/$tdir/f $NR ||
13217                 error "failed to create $NR files in $DIR/$tdir"
13218
13219         cancel_lru_locks mdc
13220         ls -l $DIR/$tdir > /dev/null
13221
13222         local NSDIR=""
13223         local LRU_SIZE=0
13224         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13225                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13226                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13227                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13228                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13229                         log "NSDIR=$NSDIR"
13230                         log "NS=$(basename $NSDIR)"
13231                         break
13232                 fi
13233         done
13234
13235         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13236                 skip "Not enough cached locks created!"
13237         fi
13238         log "LRU=$LRU_SIZE"
13239
13240         local SLEEP=30
13241
13242         # We know that lru resize allows one client to hold $LIMIT locks
13243         # for 10h. After that locks begin to be killed by client.
13244         local MAX_HRS=10
13245         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13246         log "LIMIT=$LIMIT"
13247         if [ $LIMIT -lt $LRU_SIZE ]; then
13248                 skip "Limit is too small $LIMIT"
13249         fi
13250
13251         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13252         # killing locks. Some time was spent for creating locks. This means
13253         # that up to the moment of sleep finish we must have killed some of
13254         # them (10-100 locks). This depends on how fast ther were created.
13255         # Many of them were touched in almost the same moment and thus will
13256         # be killed in groups.
13257         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13258
13259         # Use $LRU_SIZE_B here to take into account real number of locks
13260         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13261         local LRU_SIZE_B=$LRU_SIZE
13262         log "LVF=$LVF"
13263         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13264         log "OLD_LVF=$OLD_LVF"
13265         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13266
13267         # Let's make sure that we really have some margin. Client checks
13268         # cached locks every 10 sec.
13269         SLEEP=$((SLEEP+20))
13270         log "Sleep ${SLEEP} sec"
13271         local SEC=0
13272         while ((SEC<$SLEEP)); do
13273                 echo -n "..."
13274                 sleep 5
13275                 SEC=$((SEC+5))
13276                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13277                 echo -n "$LRU_SIZE"
13278         done
13279         echo ""
13280         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13281         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13282
13283         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13284                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13285                 unlinkmany $DIR/$tdir/f $NR
13286                 return
13287         }
13288
13289         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13290         log "unlink $NR files at $DIR/$tdir"
13291         unlinkmany $DIR/$tdir/f $NR
13292 }
13293 run_test 124a "lru resize ======================================="
13294
13295 get_max_pool_limit()
13296 {
13297         local limit=$($LCTL get_param \
13298                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13299         local max=0
13300         for l in $limit; do
13301                 if [[ $l -gt $max ]]; then
13302                         max=$l
13303                 fi
13304         done
13305         echo $max
13306 }
13307
13308 test_124b() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13311                 skip_env "no lru resize on server"
13312
13313         LIMIT=$(get_max_pool_limit)
13314
13315         NR=$(($(default_lru_size)*20))
13316         if [[ $NR -gt $LIMIT ]]; then
13317                 log "Limit lock number by $LIMIT locks"
13318                 NR=$LIMIT
13319         fi
13320
13321         IFree=$(mdsrate_inodes_available)
13322         if [ $IFree -lt $NR ]; then
13323                 log "Limit lock number by $IFree inodes"
13324                 NR=$IFree
13325         fi
13326
13327         lru_resize_disable mdc
13328         test_mkdir -p $DIR/$tdir/disable_lru_resize
13329
13330         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13331         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13332         cancel_lru_locks mdc
13333         stime=`date +%s`
13334         PID=""
13335         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13336         PID="$PID $!"
13337         sleep 2
13338         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13339         PID="$PID $!"
13340         sleep 2
13341         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13342         PID="$PID $!"
13343         wait $PID
13344         etime=`date +%s`
13345         nolruresize_delta=$((etime-stime))
13346         log "ls -la time: $nolruresize_delta seconds"
13347         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13348         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13349
13350         lru_resize_enable mdc
13351         test_mkdir -p $DIR/$tdir/enable_lru_resize
13352
13353         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13354         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13355         cancel_lru_locks mdc
13356         stime=`date +%s`
13357         PID=""
13358         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13359         PID="$PID $!"
13360         sleep 2
13361         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13362         PID="$PID $!"
13363         sleep 2
13364         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13365         PID="$PID $!"
13366         wait $PID
13367         etime=`date +%s`
13368         lruresize_delta=$((etime-stime))
13369         log "ls -la time: $lruresize_delta seconds"
13370         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13371
13372         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13373                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13374         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13375                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13376         else
13377                 log "lru resize performs the same with no lru resize"
13378         fi
13379         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13380 }
13381 run_test 124b "lru resize (performance test) ======================="
13382
13383 test_124c() {
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13386                 skip_env "no lru resize on server"
13387
13388         # cache ununsed locks on client
13389         local nr=100
13390         cancel_lru_locks mdc
13391         test_mkdir $DIR/$tdir
13392         createmany -o $DIR/$tdir/f $nr ||
13393                 error "failed to create $nr files in $DIR/$tdir"
13394         ls -l $DIR/$tdir > /dev/null
13395
13396         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13397         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13398         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13399         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13400         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13401
13402         # set lru_max_age to 1 sec
13403         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13404         echo "sleep $((recalc_p * 2)) seconds..."
13405         sleep $((recalc_p * 2))
13406
13407         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13408         # restore lru_max_age
13409         $LCTL set_param -n $nsdir.lru_max_age $max_age
13410         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13411         unlinkmany $DIR/$tdir/f $nr
13412 }
13413 run_test 124c "LRUR cancel very aged locks"
13414
13415 test_124d() {
13416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13417         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13418                 skip_env "no lru resize on server"
13419
13420         # cache ununsed locks on client
13421         local nr=100
13422
13423         lru_resize_disable mdc
13424         stack_trap "lru_resize_enable mdc" EXIT
13425
13426         cancel_lru_locks mdc
13427
13428         # asynchronous object destroy at MDT could cause bl ast to client
13429         test_mkdir $DIR/$tdir
13430         createmany -o $DIR/$tdir/f $nr ||
13431                 error "failed to create $nr files in $DIR/$tdir"
13432         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13433
13434         ls -l $DIR/$tdir > /dev/null
13435
13436         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13437         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13438         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13439         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13440
13441         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13442
13443         # set lru_max_age to 1 sec
13444         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13445         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13446
13447         echo "sleep $((recalc_p * 2)) seconds..."
13448         sleep $((recalc_p * 2))
13449
13450         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13451
13452         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13453 }
13454 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13455
13456 test_125() { # 13358
13457         $LCTL get_param -n llite.*.client_type | grep -q local ||
13458                 skip "must run as local client"
13459         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13460                 skip_env "must have acl enabled"
13461         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13462
13463         test_mkdir $DIR/$tdir
13464         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13465         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13466         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13467 }
13468 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13469
13470 test_126() { # bug 12829/13455
13471         $GSS && skip_env "must run as gss disabled"
13472         $LCTL get_param -n llite.*.client_type | grep -q local ||
13473                 skip "must run as local client"
13474         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13475
13476         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13477         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13478         rm -f $DIR/$tfile
13479         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13480 }
13481 run_test 126 "check that the fsgid provided by the client is taken into account"
13482
13483 test_127a() { # bug 15521
13484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13485         local name count samp unit min max sum sumsq
13486
13487         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13488         echo "stats before reset"
13489         $LCTL get_param osc.*.stats
13490         $LCTL set_param osc.*.stats=0
13491         local fsize=$((2048 * 1024))
13492
13493         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13494         cancel_lru_locks osc
13495         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13496
13497         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13498         stack_trap "rm -f $TMP/$tfile.tmp"
13499         while read name count samp unit min max sum sumsq; do
13500                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13501                 [ ! $min ] && error "Missing min value for $name proc entry"
13502                 eval $name=$count || error "Wrong proc format"
13503
13504                 case $name in
13505                 read_bytes|write_bytes)
13506                         [[ "$unit" =~ "bytes" ]] ||
13507                                 error "unit is not 'bytes': $unit"
13508                         (( $min >= 4096 )) || error "min is too small: $min"
13509                         (( $min <= $fsize )) || error "min is too big: $min"
13510                         (( $max >= 4096 )) || error "max is too small: $max"
13511                         (( $max <= $fsize )) || error "max is too big: $max"
13512                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13513                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13514                                 error "sumsquare is too small: $sumsq"
13515                         (( $sumsq <= $fsize * $fsize )) ||
13516                                 error "sumsquare is too big: $sumsq"
13517                         ;;
13518                 ost_read|ost_write)
13519                         [[ "$unit" =~ "usec" ]] ||
13520                                 error "unit is not 'usec': $unit"
13521                         ;;
13522                 *)      ;;
13523                 esac
13524         done < $DIR/$tfile.tmp
13525
13526         #check that we actually got some stats
13527         [ "$read_bytes" ] || error "Missing read_bytes stats"
13528         [ "$write_bytes" ] || error "Missing write_bytes stats"
13529         [ "$read_bytes" != 0 ] || error "no read done"
13530         [ "$write_bytes" != 0 ] || error "no write done"
13531 }
13532 run_test 127a "verify the client stats are sane"
13533
13534 test_127b() { # bug LU-333
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         local name count samp unit min max sum sumsq
13537
13538         echo "stats before reset"
13539         $LCTL get_param llite.*.stats
13540         $LCTL set_param llite.*.stats=0
13541
13542         # perform 2 reads and writes so MAX is different from SUM.
13543         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13544         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13545         cancel_lru_locks osc
13546         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13547         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13548
13549         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13550         stack_trap "rm -f $TMP/$tfile.tmp"
13551         while read name count samp unit min max sum sumsq; do
13552                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13553                 eval $name=$count || error "Wrong proc format"
13554
13555                 case $name in
13556                 read_bytes|write_bytes)
13557                         [[ "$unit" =~ "bytes" ]] ||
13558                                 error "unit is not 'bytes': $unit"
13559                         (( $count == 2 )) || error "count is not 2: $count"
13560                         (( $min == $PAGE_SIZE )) ||
13561                                 error "min is not $PAGE_SIZE: $min"
13562                         (( $max == $PAGE_SIZE )) ||
13563                                 error "max is not $PAGE_SIZE: $max"
13564                         (( $sum == $PAGE_SIZE * 2 )) ||
13565                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13566                         ;;
13567                 read|write)
13568                         [[ "$unit" =~ "usec" ]] ||
13569                                 error "unit is not 'usec': $unit"
13570                         ;;
13571                 *)      ;;
13572                 esac
13573         done < $TMP/$tfile.tmp
13574
13575         #check that we actually got some stats
13576         [ "$read_bytes" ] || error "Missing read_bytes stats"
13577         [ "$write_bytes" ] || error "Missing write_bytes stats"
13578         [ "$read_bytes" != 0 ] || error "no read done"
13579         [ "$write_bytes" != 0 ] || error "no write done"
13580 }
13581 run_test 127b "verify the llite client stats are sane"
13582
13583 test_127c() { # LU-12394
13584         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13585         local size
13586         local bsize
13587         local reads
13588         local writes
13589         local count
13590
13591         $LCTL set_param llite.*.extents_stats=1
13592         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13593
13594         # Use two stripes so there is enough space in default config
13595         $LFS setstripe -c 2 $DIR/$tfile
13596
13597         # Extent stats start at 0-4K and go in power of two buckets
13598         # LL_HIST_START = 12 --> 2^12 = 4K
13599         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13600         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13601         # small configs
13602         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13603                 do
13604                 # Write and read, 2x each, second time at a non-zero offset
13605                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13606                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13607                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13608                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13609                 rm -f $DIR/$tfile
13610         done
13611
13612         $LCTL get_param llite.*.extents_stats
13613
13614         count=2
13615         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13616                 do
13617                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13618                                 grep -m 1 $bsize)
13619                 reads=$(echo $bucket | awk '{print $5}')
13620                 writes=$(echo $bucket | awk '{print $9}')
13621                 [ "$reads" -eq $count ] ||
13622                         error "$reads reads in < $bsize bucket, expect $count"
13623                 [ "$writes" -eq $count ] ||
13624                         error "$writes writes in < $bsize bucket, expect $count"
13625         done
13626
13627         # Test mmap write and read
13628         $LCTL set_param llite.*.extents_stats=c
13629         size=512
13630         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13631         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13632         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13633
13634         $LCTL get_param llite.*.extents_stats
13635
13636         count=$(((size*1024) / PAGE_SIZE))
13637
13638         bsize=$((2 * PAGE_SIZE / 1024))K
13639
13640         bucket=$($LCTL get_param -n llite.*.extents_stats |
13641                         grep -m 1 $bsize)
13642         reads=$(echo $bucket | awk '{print $5}')
13643         writes=$(echo $bucket | awk '{print $9}')
13644         # mmap writes fault in the page first, creating an additonal read
13645         [ "$reads" -eq $((2 * count)) ] ||
13646                 error "$reads reads in < $bsize bucket, expect $count"
13647         [ "$writes" -eq $count ] ||
13648                 error "$writes writes in < $bsize bucket, expect $count"
13649 }
13650 run_test 127c "test llite extent stats with regular & mmap i/o"
13651
13652 test_128() { # bug 15212
13653         touch $DIR/$tfile
13654         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13655                 find $DIR/$tfile
13656                 find $DIR/$tfile
13657         EOF
13658
13659         result=$(grep error $TMP/$tfile.log)
13660         rm -f $DIR/$tfile $TMP/$tfile.log
13661         [ -z "$result" ] ||
13662                 error "consecutive find's under interactive lfs failed"
13663 }
13664 run_test 128 "interactive lfs for 2 consecutive find's"
13665
13666 set_dir_limits () {
13667         local mntdev
13668         local canondev
13669         local node
13670
13671         local ldproc=/proc/fs/ldiskfs
13672         local facets=$(get_facets MDS)
13673
13674         for facet in ${facets//,/ }; do
13675                 canondev=$(ldiskfs_canon \
13676                            *.$(convert_facet2label $facet).mntdev $facet)
13677                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13678                         ldproc=/sys/fs/ldiskfs
13679                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13680                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13681         done
13682 }
13683
13684 check_mds_dmesg() {
13685         local facets=$(get_facets MDS)
13686         for facet in ${facets//,/ }; do
13687                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13688         done
13689         return 1
13690 }
13691
13692 test_129() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13695                 skip "Need MDS version with at least 2.5.56"
13696         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13697                 skip_env "ldiskfs only test"
13698         fi
13699         remote_mds_nodsh && skip "remote MDS with nodsh"
13700
13701         local ENOSPC=28
13702         local has_warning=false
13703
13704         rm -rf $DIR/$tdir
13705         mkdir -p $DIR/$tdir
13706
13707         # block size of mds1
13708         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13709         set_dir_limits $maxsize $((maxsize * 6 / 8))
13710         stack_trap "set_dir_limits 0 0"
13711         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13712         local dirsize=$(stat -c%s "$DIR/$tdir")
13713         local nfiles=0
13714         while (( $dirsize <= $maxsize )); do
13715                 $MCREATE $DIR/$tdir/file_base_$nfiles
13716                 rc=$?
13717                 # check two errors:
13718                 # ENOSPC for ext4 max_dir_size, which has been used since
13719                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13720                 if (( rc == ENOSPC )); then
13721                         set_dir_limits 0 0
13722                         echo "rc=$rc returned as expected after $nfiles files"
13723
13724                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13725                                 error "create failed w/o dir size limit"
13726
13727                         # messages may be rate limited if test is run repeatedly
13728                         check_mds_dmesg '"is approaching max"' ||
13729                                 echo "warning message should be output"
13730                         check_mds_dmesg '"has reached max"' ||
13731                                 echo "reached message should be output"
13732
13733                         dirsize=$(stat -c%s "$DIR/$tdir")
13734
13735                         [[ $dirsize -ge $maxsize ]] && return 0
13736                         error "dirsize $dirsize < $maxsize after $nfiles files"
13737                 elif (( rc != 0 )); then
13738                         break
13739                 fi
13740                 nfiles=$((nfiles + 1))
13741                 dirsize=$(stat -c%s "$DIR/$tdir")
13742         done
13743
13744         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13745 }
13746 run_test 129 "test directory size limit ========================"
13747
13748 OLDIFS="$IFS"
13749 cleanup_130() {
13750         trap 0
13751         IFS="$OLDIFS"
13752 }
13753
13754 test_130a() {
13755         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13756         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13757
13758         trap cleanup_130 EXIT RETURN
13759
13760         local fm_file=$DIR/$tfile
13761         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13762         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13763                 error "dd failed for $fm_file"
13764
13765         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13766         filefrag -ves $fm_file
13767         RC=$?
13768         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13769                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13770         [ $RC != 0 ] && error "filefrag $fm_file failed"
13771
13772         filefrag_op=$(filefrag -ve -k $fm_file |
13773                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13774         lun=$($LFS getstripe -i $fm_file)
13775
13776         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13777         IFS=$'\n'
13778         tot_len=0
13779         for line in $filefrag_op
13780         do
13781                 frag_lun=`echo $line | cut -d: -f5`
13782                 ext_len=`echo $line | cut -d: -f4`
13783                 if (( $frag_lun != $lun )); then
13784                         cleanup_130
13785                         error "FIEMAP on 1-stripe file($fm_file) failed"
13786                         return
13787                 fi
13788                 (( tot_len += ext_len ))
13789         done
13790
13791         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13792                 cleanup_130
13793                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13794                 return
13795         fi
13796
13797         cleanup_130
13798
13799         echo "FIEMAP on single striped file succeeded"
13800 }
13801 run_test 130a "FIEMAP (1-stripe file)"
13802
13803 test_130b() {
13804         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13805
13806         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13807         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13808
13809         trap cleanup_130 EXIT RETURN
13810
13811         local fm_file=$DIR/$tfile
13812         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13813                         error "setstripe on $fm_file"
13814         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13815                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13816
13817         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13818                 error "dd failed on $fm_file"
13819
13820         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13821         filefrag_op=$(filefrag -ve -k $fm_file |
13822                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13823
13824         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13825                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13826
13827         IFS=$'\n'
13828         tot_len=0
13829         num_luns=1
13830         for line in $filefrag_op
13831         do
13832                 frag_lun=$(echo $line | cut -d: -f5 |
13833                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13834                 ext_len=$(echo $line | cut -d: -f4)
13835                 if (( $frag_lun != $last_lun )); then
13836                         if (( tot_len != 1024 )); then
13837                                 cleanup_130
13838                                 error "FIEMAP on $fm_file failed; returned " \
13839                                 "len $tot_len for OST $last_lun instead of 1024"
13840                                 return
13841                         else
13842                                 (( num_luns += 1 ))
13843                                 tot_len=0
13844                         fi
13845                 fi
13846                 (( tot_len += ext_len ))
13847                 last_lun=$frag_lun
13848         done
13849         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13850                 cleanup_130
13851                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13852                         "luns or wrong len for OST $last_lun"
13853                 return
13854         fi
13855
13856         cleanup_130
13857
13858         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13859 }
13860 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13861
13862 test_130c() {
13863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13864
13865         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13866         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13867
13868         trap cleanup_130 EXIT RETURN
13869
13870         local fm_file=$DIR/$tfile
13871         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13872         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13873                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13874
13875         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13876                         error "dd failed on $fm_file"
13877
13878         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13879         filefrag_op=$(filefrag -ve -k $fm_file |
13880                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13881
13882         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13883                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13884
13885         IFS=$'\n'
13886         tot_len=0
13887         num_luns=1
13888         for line in $filefrag_op
13889         do
13890                 frag_lun=$(echo $line | cut -d: -f5 |
13891                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13892                 ext_len=$(echo $line | cut -d: -f4)
13893                 if (( $frag_lun != $last_lun )); then
13894                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13895                         if (( logical != 512 )); then
13896                                 cleanup_130
13897                                 error "FIEMAP on $fm_file failed; returned " \
13898                                 "logical start for lun $logical instead of 512"
13899                                 return
13900                         fi
13901                         if (( tot_len != 512 )); then
13902                                 cleanup_130
13903                                 error "FIEMAP on $fm_file failed; returned " \
13904                                 "len $tot_len for OST $last_lun instead of 1024"
13905                                 return
13906                         else
13907                                 (( num_luns += 1 ))
13908                                 tot_len=0
13909                         fi
13910                 fi
13911                 (( tot_len += ext_len ))
13912                 last_lun=$frag_lun
13913         done
13914         if (( num_luns != 2 || tot_len != 512 )); then
13915                 cleanup_130
13916                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13917                         "luns or wrong len for OST $last_lun"
13918                 return
13919         fi
13920
13921         cleanup_130
13922
13923         echo "FIEMAP on 2-stripe file with hole succeeded"
13924 }
13925 run_test 130c "FIEMAP (2-stripe file with hole)"
13926
13927 test_130d() {
13928         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13929
13930         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13931         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13932
13933         trap cleanup_130 EXIT RETURN
13934
13935         local fm_file=$DIR/$tfile
13936         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13937                         error "setstripe on $fm_file"
13938         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13939                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13940
13941         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13942         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13943                 error "dd failed on $fm_file"
13944
13945         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13946         filefrag_op=$(filefrag -ve -k $fm_file |
13947                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13948
13949         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13950                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13951
13952         IFS=$'\n'
13953         tot_len=0
13954         num_luns=1
13955         for line in $filefrag_op
13956         do
13957                 frag_lun=$(echo $line | cut -d: -f5 |
13958                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13959                 ext_len=$(echo $line | cut -d: -f4)
13960                 if (( $frag_lun != $last_lun )); then
13961                         if (( tot_len != 1024 )); then
13962                                 cleanup_130
13963                                 error "FIEMAP on $fm_file failed; returned " \
13964                                 "len $tot_len for OST $last_lun instead of 1024"
13965                                 return
13966                         else
13967                                 (( num_luns += 1 ))
13968                                 tot_len=0
13969                         fi
13970                 fi
13971                 (( tot_len += ext_len ))
13972                 last_lun=$frag_lun
13973         done
13974         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13975                 cleanup_130
13976                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13977                         "luns or wrong len for OST $last_lun"
13978                 return
13979         fi
13980
13981         cleanup_130
13982
13983         echo "FIEMAP on N-stripe file succeeded"
13984 }
13985 run_test 130d "FIEMAP (N-stripe file)"
13986
13987 test_130e() {
13988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13989
13990         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13991         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13992
13993         trap cleanup_130 EXIT RETURN
13994
13995         local fm_file=$DIR/$tfile
13996         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13997
13998         NUM_BLKS=512
13999         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
14000         for ((i = 0; i < $NUM_BLKS; i++)); do
14001                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14002                         conv=notrunc > /dev/null 2>&1
14003         done
14004
14005         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14006         filefrag_op=$(filefrag -ve -k $fm_file |
14007                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14008
14009         last_lun=$(echo $filefrag_op | cut -d: -f5)
14010
14011         IFS=$'\n'
14012         tot_len=0
14013         num_luns=1
14014         for line in $filefrag_op; do
14015                 frag_lun=$(echo $line | cut -d: -f5)
14016                 ext_len=$(echo $line | cut -d: -f4)
14017                 if [[ "$frag_lun" != "$last_lun" ]]; then
14018                         if (( tot_len != $EXPECTED_LEN )); then
14019                                 cleanup_130
14020                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14021                         else
14022                                 (( num_luns += 1 ))
14023                                 tot_len=0
14024                         fi
14025                 fi
14026                 (( tot_len += ext_len ))
14027                 last_lun=$frag_lun
14028         done
14029         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14030                 cleanup_130
14031                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14032         fi
14033
14034         echo "FIEMAP with continuation calls succeeded"
14035 }
14036 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14037
14038 test_130f() {
14039         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14040         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14041
14042         local fm_file=$DIR/$tfile
14043         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14044                 error "multiop create with lov_delay_create on $fm_file"
14045
14046         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14047         filefrag_extents=$(filefrag -vek $fm_file |
14048                            awk '/extents? found/ { print $2 }')
14049         if [[ "$filefrag_extents" != "0" ]]; then
14050                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14051         fi
14052
14053         rm -f $fm_file
14054 }
14055 run_test 130f "FIEMAP (unstriped file)"
14056
14057 test_130g() {
14058         local file=$DIR/$tfile
14059         local nr=$((OSTCOUNT * 100))
14060
14061         $LFS setstripe -C $nr $file ||
14062                 error "failed to setstripe -C $nr $file"
14063
14064         dd if=/dev/zero of=$file count=$nr bs=1M
14065         sync
14066         nr=$($LFS getstripe -c $file)
14067
14068         local extents=$(filefrag -v $file |
14069                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14070
14071         echo "filefrag list $extents extents in file with stripecount $nr"
14072         if (( extents < nr )); then
14073                 $LFS getstripe $file
14074                 filefrag -v $file
14075                 error "filefrag printed $extents < $nr extents"
14076         fi
14077
14078         rm -f $file
14079 }
14080 run_test 130g "FIEMAP (overstripe file)"
14081
14082 # Test for writev/readv
14083 test_131a() {
14084         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14085                 error "writev test failed"
14086         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14087                 error "readv failed"
14088         rm -f $DIR/$tfile
14089 }
14090 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14091
14092 test_131b() {
14093         local fsize=$((524288 + 1048576 + 1572864))
14094         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14095                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14096                         error "append writev test failed"
14097
14098         ((fsize += 1572864 + 1048576))
14099         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14100                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14101                         error "append writev test failed"
14102         rm -f $DIR/$tfile
14103 }
14104 run_test 131b "test append writev"
14105
14106 test_131c() {
14107         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14108         error "NOT PASS"
14109 }
14110 run_test 131c "test read/write on file w/o objects"
14111
14112 test_131d() {
14113         rwv -f $DIR/$tfile -w -n 1 1572864
14114         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14115         if [ "$NOB" != 1572864 ]; then
14116                 error "Short read filed: read $NOB bytes instead of 1572864"
14117         fi
14118         rm -f $DIR/$tfile
14119 }
14120 run_test 131d "test short read"
14121
14122 test_131e() {
14123         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14124         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14125         error "read hitting hole failed"
14126         rm -f $DIR/$tfile
14127 }
14128 run_test 131e "test read hitting hole"
14129
14130 check_stats() {
14131         local facet=$1
14132         local op=$2
14133         local want=${3:-0}
14134         local res
14135
14136         case $facet in
14137         mds*) res=$(do_facet $facet \
14138                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14139                  ;;
14140         ost*) res=$(do_facet $facet \
14141                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14142                  ;;
14143         *) error "Wrong facet '$facet'" ;;
14144         esac
14145         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14146         # if the argument $3 is zero, it means any stat increment is ok.
14147         if [[ $want -gt 0 ]]; then
14148                 local count=$(echo $res | awk '{ print $2 }')
14149                 [[ $count -ne $want ]] &&
14150                         error "The $op counter on $facet is $count, not $want"
14151         fi
14152 }
14153
14154 test_133a() {
14155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14156         remote_ost_nodsh && skip "remote OST with nodsh"
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14159                 skip_env "MDS doesn't support rename stats"
14160
14161         local testdir=$DIR/${tdir}/stats_testdir
14162
14163         mkdir -p $DIR/${tdir}
14164
14165         # clear stats.
14166         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14167         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14168
14169         # verify mdt stats first.
14170         mkdir ${testdir} || error "mkdir failed"
14171         check_stats $SINGLEMDS "mkdir" 1
14172         touch ${testdir}/${tfile} || error "touch failed"
14173         check_stats $SINGLEMDS "open" 1
14174         check_stats $SINGLEMDS "close" 1
14175         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14176                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14177                 check_stats $SINGLEMDS "mknod" 2
14178         }
14179         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14180         check_stats $SINGLEMDS "unlink" 1
14181         rm -f ${testdir}/${tfile} || error "file remove failed"
14182         check_stats $SINGLEMDS "unlink" 2
14183
14184         # remove working dir and check mdt stats again.
14185         rmdir ${testdir} || error "rmdir failed"
14186         check_stats $SINGLEMDS "rmdir" 1
14187
14188         local testdir1=$DIR/${tdir}/stats_testdir1
14189         mkdir -p ${testdir}
14190         mkdir -p ${testdir1}
14191         touch ${testdir1}/test1
14192         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14193         check_stats $SINGLEMDS "crossdir_rename" 1
14194
14195         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14196         check_stats $SINGLEMDS "samedir_rename" 1
14197
14198         rm -rf $DIR/${tdir}
14199 }
14200 run_test 133a "Verifying MDT stats ========================================"
14201
14202 test_133b() {
14203         local res
14204
14205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14206         remote_ost_nodsh && skip "remote OST with nodsh"
14207         remote_mds_nodsh && skip "remote MDS with nodsh"
14208
14209         local testdir=$DIR/${tdir}/stats_testdir
14210
14211         mkdir -p ${testdir} || error "mkdir failed"
14212         touch ${testdir}/${tfile} || error "touch failed"
14213         cancel_lru_locks mdc
14214
14215         # clear stats.
14216         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14217         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14218
14219         # extra mdt stats verification.
14220         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14221         check_stats $SINGLEMDS "setattr" 1
14222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14223         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14224         then            # LU-1740
14225                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14226                 check_stats $SINGLEMDS "getattr" 1
14227         fi
14228         rm -rf $DIR/${tdir}
14229
14230         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14231         # so the check below is not reliable
14232         [ $MDSCOUNT -eq 1 ] || return 0
14233
14234         # Sleep to avoid a cached response.
14235         #define OBD_STATFS_CACHE_SECONDS 1
14236         sleep 2
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14238         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14239         $LFS df || error "lfs failed"
14240         check_stats $SINGLEMDS "statfs" 1
14241
14242         # check aggregated statfs (LU-10018)
14243         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14244                 return 0
14245         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14246                 return 0
14247         sleep 2
14248         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14249         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14250         df $DIR
14251         check_stats $SINGLEMDS "statfs" 1
14252
14253         # We want to check that the client didn't send OST_STATFS to
14254         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14255         # extra care is needed here.
14256         if remote_mds; then
14257                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14258                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14259
14260                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14261                 [ "$res" ] && error "OST got STATFS"
14262         fi
14263
14264         return 0
14265 }
14266 run_test 133b "Verifying extra MDT stats =================================="
14267
14268 test_133c() {
14269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14270         remote_ost_nodsh && skip "remote OST with nodsh"
14271         remote_mds_nodsh && skip "remote MDS with nodsh"
14272
14273         local testdir=$DIR/$tdir/stats_testdir
14274
14275         test_mkdir -p $testdir
14276
14277         # verify obdfilter stats.
14278         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14279         sync
14280         cancel_lru_locks osc
14281         wait_delete_completed
14282
14283         # clear stats.
14284         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14285         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14286
14287         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14288                 error "dd failed"
14289         sync
14290         cancel_lru_locks osc
14291         check_stats ost1 "write" 1
14292
14293         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14294         check_stats ost1 "read" 1
14295
14296         > $testdir/$tfile || error "truncate failed"
14297         check_stats ost1 "punch" 1
14298
14299         rm -f $testdir/$tfile || error "file remove failed"
14300         wait_delete_completed
14301         check_stats ost1 "destroy" 1
14302
14303         rm -rf $DIR/$tdir
14304 }
14305 run_test 133c "Verifying OST stats ========================================"
14306
14307 order_2() {
14308         local value=$1
14309         local orig=$value
14310         local order=1
14311
14312         while [ $value -ge 2 ]; do
14313                 order=$((order*2))
14314                 value=$((value/2))
14315         done
14316
14317         if [ $orig -gt $order ]; then
14318                 order=$((order*2))
14319         fi
14320         echo $order
14321 }
14322
14323 size_in_KMGT() {
14324     local value=$1
14325     local size=('K' 'M' 'G' 'T');
14326     local i=0
14327     local size_string=$value
14328
14329     while [ $value -ge 1024 ]; do
14330         if [ $i -gt 3 ]; then
14331             #T is the biggest unit we get here, if that is bigger,
14332             #just return XXXT
14333             size_string=${value}T
14334             break
14335         fi
14336         value=$((value >> 10))
14337         if [ $value -lt 1024 ]; then
14338             size_string=${value}${size[$i]}
14339             break
14340         fi
14341         i=$((i + 1))
14342     done
14343
14344     echo $size_string
14345 }
14346
14347 get_rename_size() {
14348         local size=$1
14349         local context=${2:-.}
14350         local sample=$(do_facet $SINGLEMDS $LCTL \
14351                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14352                 grep -A1 $context |
14353                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14354         echo $sample
14355 }
14356
14357 test_133d() {
14358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14359         remote_ost_nodsh && skip "remote OST with nodsh"
14360         remote_mds_nodsh && skip "remote MDS with nodsh"
14361         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14362                 skip_env "MDS doesn't support rename stats"
14363
14364         local testdir1=$DIR/${tdir}/stats_testdir1
14365         local testdir2=$DIR/${tdir}/stats_testdir2
14366         mkdir -p $DIR/${tdir}
14367
14368         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14369
14370         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14371         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14372
14373         createmany -o $testdir1/test 512 || error "createmany failed"
14374
14375         # check samedir rename size
14376         mv ${testdir1}/test0 ${testdir1}/test_0
14377
14378         local testdir1_size=$(ls -l $DIR/${tdir} |
14379                 awk '/stats_testdir1/ {print $5}')
14380         local testdir2_size=$(ls -l $DIR/${tdir} |
14381                 awk '/stats_testdir2/ {print $5}')
14382
14383         testdir1_size=$(order_2 $testdir1_size)
14384         testdir2_size=$(order_2 $testdir2_size)
14385
14386         testdir1_size=$(size_in_KMGT $testdir1_size)
14387         testdir2_size=$(size_in_KMGT $testdir2_size)
14388
14389         echo "source rename dir size: ${testdir1_size}"
14390         echo "target rename dir size: ${testdir2_size}"
14391
14392         local cmd="do_facet $SINGLEMDS $LCTL "
14393         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14394
14395         eval $cmd || error "$cmd failed"
14396         local samedir=$($cmd | grep 'same_dir')
14397         local same_sample=$(get_rename_size $testdir1_size)
14398         [ -z "$samedir" ] && error "samedir_rename_size count error"
14399         [[ $same_sample -eq 1 ]] ||
14400                 error "samedir_rename_size error $same_sample"
14401         echo "Check same dir rename stats success"
14402
14403         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14404
14405         # check crossdir rename size
14406         mv ${testdir1}/test_0 ${testdir2}/test_0
14407
14408         testdir1_size=$(ls -l $DIR/${tdir} |
14409                 awk '/stats_testdir1/ {print $5}')
14410         testdir2_size=$(ls -l $DIR/${tdir} |
14411                 awk '/stats_testdir2/ {print $5}')
14412
14413         testdir1_size=$(order_2 $testdir1_size)
14414         testdir2_size=$(order_2 $testdir2_size)
14415
14416         testdir1_size=$(size_in_KMGT $testdir1_size)
14417         testdir2_size=$(size_in_KMGT $testdir2_size)
14418
14419         echo "source rename dir size: ${testdir1_size}"
14420         echo "target rename dir size: ${testdir2_size}"
14421
14422         eval $cmd || error "$cmd failed"
14423         local crossdir=$($cmd | grep 'crossdir')
14424         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14425         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14426         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14427         [[ $src_sample -eq 1 ]] ||
14428                 error "crossdir_rename_size error $src_sample"
14429         [[ $tgt_sample -eq 1 ]] ||
14430                 error "crossdir_rename_size error $tgt_sample"
14431         echo "Check cross dir rename stats success"
14432         rm -rf $DIR/${tdir}
14433 }
14434 run_test 133d "Verifying rename_stats ========================================"
14435
14436 test_133e() {
14437         remote_mds_nodsh && skip "remote MDS with nodsh"
14438         remote_ost_nodsh && skip "remote OST with nodsh"
14439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14440
14441         local testdir=$DIR/${tdir}/stats_testdir
14442         local ctr f0 f1 bs=32768 count=42 sum
14443
14444         mkdir -p ${testdir} || error "mkdir failed"
14445
14446         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14447
14448         for ctr in {write,read}_bytes; do
14449                 sync
14450                 cancel_lru_locks osc
14451
14452                 do_facet ost1 $LCTL set_param -n \
14453                         "obdfilter.*.exports.clear=clear"
14454
14455                 if [ $ctr = write_bytes ]; then
14456                         f0=/dev/zero
14457                         f1=${testdir}/${tfile}
14458                 else
14459                         f0=${testdir}/${tfile}
14460                         f1=/dev/null
14461                 fi
14462
14463                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14464                         error "dd failed"
14465                 sync
14466                 cancel_lru_locks osc
14467
14468                 sum=$(do_facet ost1 $LCTL get_param \
14469                         "obdfilter.*.exports.*.stats" |
14470                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14471                                 $1 == ctr { sum += $7 }
14472                                 END { printf("%0.0f", sum) }')
14473
14474                 if ((sum != bs * count)); then
14475                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14476                 fi
14477         done
14478
14479         rm -rf $DIR/${tdir}
14480 }
14481 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14482
14483 test_133f() {
14484         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14485                 skip "too old lustre for get_param -R ($facet_ver)"
14486
14487         # verifying readability.
14488         $LCTL get_param -R '*' &> /dev/null
14489
14490         # Verifing writability with badarea_io.
14491         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14492         local skipped_params='force_lbug|changelog_mask|daemon_file'
14493         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14494                 egrep -v "$skipped_params" |
14495                 xargs -n 1 find $proc_dirs -name |
14496                 xargs -n 1 badarea_io ||
14497                 error "client badarea_io failed"
14498
14499         # remount the FS in case writes/reads /proc break the FS
14500         cleanup || error "failed to unmount"
14501         setup || error "failed to setup"
14502 }
14503 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14504
14505 test_133g() {
14506         remote_mds_nodsh && skip "remote MDS with nodsh"
14507         remote_ost_nodsh && skip "remote OST with nodsh"
14508
14509         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14510         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14511         local facet
14512         for facet in mds1 ost1; do
14513                 local facet_ver=$(lustre_version_code $facet)
14514                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14515                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14516                 else
14517                         log "$facet: too old lustre for get_param -R"
14518                 fi
14519                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14520                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14521                                 tr -d = | egrep -v $skipped_params |
14522                                 xargs -n 1 find $proc_dirs -name |
14523                                 xargs -n 1 badarea_io" ||
14524                                         error "$facet badarea_io failed"
14525                 else
14526                         skip_noexit "$facet: too old lustre for get_param -R"
14527                 fi
14528         done
14529
14530         # remount the FS in case writes/reads /proc break the FS
14531         cleanup || error "failed to unmount"
14532         setup || error "failed to setup"
14533 }
14534 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14535
14536 test_133h() {
14537         remote_mds_nodsh && skip "remote MDS with nodsh"
14538         remote_ost_nodsh && skip "remote OST with nodsh"
14539         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14540                 skip "Need MDS version at least 2.9.54"
14541
14542         local facet
14543         for facet in client mds1 ost1; do
14544                 # Get the list of files that are missing the terminating newline
14545                 local plist=$(do_facet $facet
14546                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14547                 local ent
14548                 for ent in $plist; do
14549                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14550                                 awk -v FS='\v' -v RS='\v\v' \
14551                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14552                                         print FILENAME}'" 2>/dev/null)
14553                         [ -z $missing ] || {
14554                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14555                                 error "file does not end with newline: $facet-$ent"
14556                         }
14557                 done
14558         done
14559 }
14560 run_test 133h "Proc files should end with newlines"
14561
14562 test_134a() {
14563         remote_mds_nodsh && skip "remote MDS with nodsh"
14564         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14565                 skip "Need MDS version at least 2.7.54"
14566
14567         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14568         cancel_lru_locks mdc
14569
14570         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14571         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14572         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14573
14574         local nr=1000
14575         createmany -o $DIR/$tdir/f $nr ||
14576                 error "failed to create $nr files in $DIR/$tdir"
14577         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14578
14579         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14580         do_facet mds1 $LCTL set_param fail_loc=0x327
14581         do_facet mds1 $LCTL set_param fail_val=500
14582         touch $DIR/$tdir/m
14583
14584         echo "sleep 10 seconds ..."
14585         sleep 10
14586         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14587
14588         do_facet mds1 $LCTL set_param fail_loc=0
14589         do_facet mds1 $LCTL set_param fail_val=0
14590         [ $lck_cnt -lt $unused ] ||
14591                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14592
14593         rm $DIR/$tdir/m
14594         unlinkmany $DIR/$tdir/f $nr
14595 }
14596 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14597
14598 test_134b() {
14599         remote_mds_nodsh && skip "remote MDS with nodsh"
14600         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14601                 skip "Need MDS version at least 2.7.54"
14602
14603         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14604         cancel_lru_locks mdc
14605
14606         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14607                         ldlm.lock_reclaim_threshold_mb)
14608         # disable reclaim temporarily
14609         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14610
14611         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14612         do_facet mds1 $LCTL set_param fail_loc=0x328
14613         do_facet mds1 $LCTL set_param fail_val=500
14614
14615         $LCTL set_param debug=+trace
14616
14617         local nr=600
14618         createmany -o $DIR/$tdir/f $nr &
14619         local create_pid=$!
14620
14621         echo "Sleep $TIMEOUT seconds ..."
14622         sleep $TIMEOUT
14623         if ! ps -p $create_pid  > /dev/null 2>&1; then
14624                 do_facet mds1 $LCTL set_param fail_loc=0
14625                 do_facet mds1 $LCTL set_param fail_val=0
14626                 do_facet mds1 $LCTL set_param \
14627                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14628                 error "createmany finished incorrectly!"
14629         fi
14630         do_facet mds1 $LCTL set_param fail_loc=0
14631         do_facet mds1 $LCTL set_param fail_val=0
14632         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14633         wait $create_pid || return 1
14634
14635         unlinkmany $DIR/$tdir/f $nr
14636 }
14637 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14638
14639 test_135() {
14640         remote_mds_nodsh && skip "remote MDS with nodsh"
14641         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14642                 skip "Need MDS version at least 2.13.50"
14643         local fname
14644
14645         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14646
14647 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14648         #set only one record at plain llog
14649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14650
14651         #fill already existed plain llog each 64767
14652         #wrapping whole catalog
14653         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14654
14655         createmany -o $DIR/$tdir/$tfile_ 64700
14656         for (( i = 0; i < 64700; i = i + 2 ))
14657         do
14658                 rm $DIR/$tdir/$tfile_$i &
14659                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14660                 local pid=$!
14661                 wait $pid
14662         done
14663
14664         #waiting osp synchronization
14665         wait_delete_completed
14666 }
14667 run_test 135 "Race catalog processing"
14668
14669 test_136() {
14670         remote_mds_nodsh && skip "remote MDS with nodsh"
14671         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14672                 skip "Need MDS version at least 2.13.50"
14673         local fname
14674
14675         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14676         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14677         #set only one record at plain llog
14678 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14680
14681         #fill already existed 2 plain llogs each 64767
14682         #wrapping whole catalog
14683         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14684         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14685         wait_delete_completed
14686
14687         createmany -o $DIR/$tdir/$tfile_ 10
14688         sleep 25
14689
14690         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14691         for (( i = 0; i < 10; i = i + 3 ))
14692         do
14693                 rm $DIR/$tdir/$tfile_$i &
14694                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14695                 local pid=$!
14696                 wait $pid
14697                 sleep 7
14698                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14699         done
14700
14701         #waiting osp synchronization
14702         wait_delete_completed
14703 }
14704 run_test 136 "Race catalog processing 2"
14705
14706 test_140() { #bug-17379
14707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14708
14709         test_mkdir $DIR/$tdir
14710         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14711         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14712
14713         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14714         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14715         local i=0
14716         while i=$((i + 1)); do
14717                 test_mkdir $i
14718                 cd $i || error "Changing to $i"
14719                 ln -s ../stat stat || error "Creating stat symlink"
14720                 # Read the symlink until ELOOP present,
14721                 # not LBUGing the system is considered success,
14722                 # we didn't overrun the stack.
14723                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14724                 if [ $ret -ne 0 ]; then
14725                         if [ $ret -eq 40 ]; then
14726                                 break  # -ELOOP
14727                         else
14728                                 error "Open stat symlink"
14729                                         return
14730                         fi
14731                 fi
14732         done
14733         i=$((i - 1))
14734         echo "The symlink depth = $i"
14735         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14736                 error "Invalid symlink depth"
14737
14738         # Test recursive symlink
14739         ln -s symlink_self symlink_self
14740         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14741         echo "open symlink_self returns $ret"
14742         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14743 }
14744 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14745
14746 test_150a() {
14747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14748
14749         local TF="$TMP/$tfile"
14750
14751         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14752         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14753         cp $TF $DIR/$tfile
14754         cancel_lru_locks $OSC
14755         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14756         remount_client $MOUNT
14757         df -P $MOUNT
14758         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14759
14760         $TRUNCATE $TF 6000
14761         $TRUNCATE $DIR/$tfile 6000
14762         cancel_lru_locks $OSC
14763         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14764
14765         echo "12345" >>$TF
14766         echo "12345" >>$DIR/$tfile
14767         cancel_lru_locks $OSC
14768         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14769
14770         echo "12345" >>$TF
14771         echo "12345" >>$DIR/$tfile
14772         cancel_lru_locks $OSC
14773         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14774 }
14775 run_test 150a "truncate/append tests"
14776
14777 test_150b() {
14778         check_set_fallocate_or_skip
14779
14780         touch $DIR/$tfile
14781         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14782         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14783 }
14784 run_test 150b "Verify fallocate (prealloc) functionality"
14785
14786 test_150bb() {
14787         check_set_fallocate_or_skip
14788
14789         touch $DIR/$tfile
14790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14791         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14792         > $DIR/$tfile
14793         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14794         # precomputed md5sum for 20MB of zeroes
14795         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14796         local sum=($(md5sum $DIR/$tfile))
14797
14798         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14799
14800         check_set_fallocate 1
14801
14802         > $DIR/$tfile
14803         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14804         sum=($(md5sum $DIR/$tfile))
14805
14806         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14807 }
14808 run_test 150bb "Verify fallocate modes both zero space"
14809
14810 test_150c() {
14811         check_set_fallocate_or_skip
14812         local striping="-c2"
14813
14814         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14815         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14816         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14817         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14818         local want=$((OSTCOUNT * 1048576))
14819
14820         # Must allocate all requested space, not more than 5% extra
14821         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14822                 error "bytes $bytes is not $want"
14823
14824         rm -f $DIR/$tfile
14825
14826         echo "verify fallocate on PFL file"
14827
14828         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14829
14830         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14831                 error "Create $DIR/$tfile failed"
14832         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14833         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14834         want=$((512 * 1048576))
14835
14836         # Must allocate all requested space, not more than 5% extra
14837         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14838                 error "bytes $bytes is not $want"
14839 }
14840 run_test 150c "Verify fallocate Size and Blocks"
14841
14842 test_150d() {
14843         check_set_fallocate_or_skip
14844         local striping="-c2"
14845
14846         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14847
14848         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14849         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14850                 error "setstripe failed"
14851         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14852         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14853         local want=$((OSTCOUNT * 1048576))
14854
14855         # Must allocate all requested space, not more than 5% extra
14856         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14857                 error "bytes $bytes is not $want"
14858 }
14859 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14860
14861 test_150e() {
14862         check_set_fallocate_or_skip
14863
14864         echo "df before:"
14865         $LFS df
14866         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14867         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14868                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14869
14870         # Find OST with Minimum Size
14871         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14872                        sort -un | head -1)
14873
14874         # Get 100MB per OST of the available space to reduce run time
14875         # else 60% of the available space if we are running SLOW tests
14876         if [ $SLOW == "no" ]; then
14877                 local space=$((1024 * 100 * OSTCOUNT))
14878         else
14879                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14880         fi
14881
14882         fallocate -l${space}k $DIR/$tfile ||
14883                 error "fallocate ${space}k $DIR/$tfile failed"
14884         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14885
14886         # get size immediately after fallocate. This should be correctly
14887         # updated
14888         local size=$(stat -c '%s' $DIR/$tfile)
14889         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14890
14891         # Sleep for a while for statfs to get updated. And not pull from cache.
14892         sleep 2
14893
14894         echo "df after fallocate:"
14895         $LFS df
14896
14897         (( size / 1024 == space )) || error "size $size != requested $space"
14898         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14899                 error "used $used < space $space"
14900
14901         rm $DIR/$tfile || error "rm failed"
14902         sync
14903         wait_delete_completed
14904
14905         echo "df after unlink:"
14906         $LFS df
14907 }
14908 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14909
14910 test_150f() {
14911         local size
14912         local blocks
14913         local want_size_before=20480 # in bytes
14914         local want_blocks_before=40 # 512 sized blocks
14915         local want_blocks_after=24  # 512 sized blocks
14916         local length=$(((want_blocks_before - want_blocks_after) * 512))
14917
14918         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14919                 skip "need at least 2.14.0 for fallocate punch"
14920
14921         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14922                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14923         fi
14924
14925         check_set_fallocate_or_skip
14926         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14927
14928         [[ "x$DOM" == "xyes" ]] &&
14929                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14930
14931         echo "Verify fallocate punch: Range within the file range"
14932         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14933                 error "dd failed for bs 4096 and count 5"
14934
14935         # Call fallocate with punch range which is within the file range
14936         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14937                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14938         # client must see changes immediately after fallocate
14939         size=$(stat -c '%s' $DIR/$tfile)
14940         blocks=$(stat -c '%b' $DIR/$tfile)
14941
14942         # Verify punch worked.
14943         (( blocks == want_blocks_after )) ||
14944                 error "punch failed: blocks $blocks != $want_blocks_after"
14945
14946         (( size == want_size_before )) ||
14947                 error "punch failed: size $size != $want_size_before"
14948
14949         # Verify there is hole in file
14950         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14951         # precomputed md5sum
14952         local expect="4a9a834a2db02452929c0a348273b4aa"
14953
14954         cksum=($(md5sum $DIR/$tfile))
14955         [[ "${cksum[0]}" == "$expect" ]] ||
14956                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14957
14958         # Start second sub-case for fallocate punch.
14959         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14960         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14961                 error "dd failed for bs 4096 and count 5"
14962
14963         # Punch range less than block size will have no change in block count
14964         want_blocks_after=40  # 512 sized blocks
14965
14966         # Punch overlaps two blocks and less than blocksize
14967         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14968                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14969         size=$(stat -c '%s' $DIR/$tfile)
14970         blocks=$(stat -c '%b' $DIR/$tfile)
14971
14972         # Verify punch worked.
14973         (( blocks == want_blocks_after )) ||
14974                 error "punch failed: blocks $blocks != $want_blocks_after"
14975
14976         (( size == want_size_before )) ||
14977                 error "punch failed: size $size != $want_size_before"
14978
14979         # Verify if range is really zero'ed out. We expect Zeros.
14980         # precomputed md5sum
14981         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14982         cksum=($(md5sum $DIR/$tfile))
14983         [[ "${cksum[0]}" == "$expect" ]] ||
14984                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14985 }
14986 run_test 150f "Verify fallocate punch functionality"
14987
14988 test_150g() {
14989         local space
14990         local size
14991         local blocks
14992         local blocks_after
14993         local size_after
14994         local BS=4096 # Block size in bytes
14995
14996         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14997                 skip "need at least 2.14.0 for fallocate punch"
14998
14999         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15000                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15001         fi
15002
15003         check_set_fallocate_or_skip
15004         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15005
15006         if [[ "x$DOM" == "xyes" ]]; then
15007                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15008                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15009         else
15010                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15011                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15012         fi
15013
15014         # Get 100MB per OST of the available space to reduce run time
15015         # else 60% of the available space if we are running SLOW tests
15016         if [ $SLOW == "no" ]; then
15017                 space=$((1024 * 100 * OSTCOUNT))
15018         else
15019                 # Find OST with Minimum Size
15020                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15021                         sort -un | head -1)
15022                 echo "min size OST: $space"
15023                 space=$(((space * 60)/100 * OSTCOUNT))
15024         fi
15025         # space in 1k units, round to 4k blocks
15026         local blkcount=$((space * 1024 / $BS))
15027
15028         echo "Verify fallocate punch: Very large Range"
15029         fallocate -l${space}k $DIR/$tfile ||
15030                 error "fallocate ${space}k $DIR/$tfile failed"
15031         # write 1M at the end, start and in the middle
15032         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15033                 error "dd failed: bs $BS count 256"
15034         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15035                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15036         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15037                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15038
15039         # Gather stats.
15040         size=$(stat -c '%s' $DIR/$tfile)
15041
15042         # gather punch length.
15043         local punch_size=$((size - (BS * 2)))
15044
15045         echo "punch_size = $punch_size"
15046         echo "size - punch_size: $((size - punch_size))"
15047         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15048
15049         # Call fallocate to punch all except 2 blocks. We leave the
15050         # first and the last block
15051         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15052         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15053                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15054
15055         size_after=$(stat -c '%s' $DIR/$tfile)
15056         blocks_after=$(stat -c '%b' $DIR/$tfile)
15057
15058         # Verify punch worked.
15059         # Size should be kept
15060         (( size == size_after )) ||
15061                 error "punch failed: size $size != $size_after"
15062
15063         # two 4k data blocks to remain plus possible 1 extra extent block
15064         (( blocks_after <= ((BS / 512) * 3) )) ||
15065                 error "too many blocks remains: $blocks_after"
15066
15067         # Verify that file has hole between the first and the last blocks
15068         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15069         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15070
15071         echo "Hole at [$hole_start, $hole_end)"
15072         (( hole_start == BS )) ||
15073                 error "no hole at offset $BS after punch"
15074
15075         (( hole_end == BS + punch_size )) ||
15076                 error "data at offset $hole_end < $((BS + punch_size))"
15077 }
15078 run_test 150g "Verify fallocate punch on large range"
15079
15080 #LU-2902 roc_hit was not able to read all values from lproc
15081 function roc_hit_init() {
15082         local list=$(comma_list $(osts_nodes))
15083         local dir=$DIR/$tdir-check
15084         local file=$dir/$tfile
15085         local BEFORE
15086         local AFTER
15087         local idx
15088
15089         test_mkdir $dir
15090         #use setstripe to do a write to every ost
15091         for i in $(seq 0 $((OSTCOUNT-1))); do
15092                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15093                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15094                 idx=$(printf %04x $i)
15095                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15096                         awk '$1 == "cache_access" {sum += $7}
15097                                 END { printf("%0.0f", sum) }')
15098
15099                 cancel_lru_locks osc
15100                 cat $file >/dev/null
15101
15102                 AFTER=$(get_osd_param $list *OST*$idx stats |
15103                         awk '$1 == "cache_access" {sum += $7}
15104                                 END { printf("%0.0f", sum) }')
15105
15106                 echo BEFORE:$BEFORE AFTER:$AFTER
15107                 if ! let "AFTER - BEFORE == 4"; then
15108                         rm -rf $dir
15109                         error "roc_hit is not safe to use"
15110                 fi
15111                 rm $file
15112         done
15113
15114         rm -rf $dir
15115 }
15116
15117 function roc_hit() {
15118         local list=$(comma_list $(osts_nodes))
15119         echo $(get_osd_param $list '' stats |
15120                 awk '$1 == "cache_hit" {sum += $7}
15121                         END { printf("%0.0f", sum) }')
15122 }
15123
15124 function set_cache() {
15125         local on=1
15126
15127         if [ "$2" == "off" ]; then
15128                 on=0;
15129         fi
15130         local list=$(comma_list $(osts_nodes))
15131         set_osd_param $list '' $1_cache_enable $on
15132
15133         cancel_lru_locks osc
15134 }
15135
15136 test_151() {
15137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15138         remote_ost_nodsh && skip "remote OST with nodsh"
15139
15140         local CPAGES=3
15141         local list=$(comma_list $(osts_nodes))
15142
15143         # check whether obdfilter is cache capable at all
15144         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15145                 skip "not cache-capable obdfilter"
15146         fi
15147
15148         # check cache is enabled on all obdfilters
15149         if get_osd_param $list '' read_cache_enable | grep 0; then
15150                 skip "oss cache is disabled"
15151         fi
15152
15153         set_osd_param $list '' writethrough_cache_enable 1
15154
15155         # check write cache is enabled on all obdfilters
15156         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15157                 skip "oss write cache is NOT enabled"
15158         fi
15159
15160         roc_hit_init
15161
15162         #define OBD_FAIL_OBD_NO_LRU  0x609
15163         do_nodes $list $LCTL set_param fail_loc=0x609
15164
15165         # pages should be in the case right after write
15166         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15167                 error "dd failed"
15168
15169         local BEFORE=$(roc_hit)
15170         cancel_lru_locks osc
15171         cat $DIR/$tfile >/dev/null
15172         local AFTER=$(roc_hit)
15173
15174         do_nodes $list $LCTL set_param fail_loc=0
15175
15176         if ! let "AFTER - BEFORE == CPAGES"; then
15177                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15178         fi
15179
15180         cancel_lru_locks osc
15181         # invalidates OST cache
15182         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15183         set_osd_param $list '' read_cache_enable 0
15184         cat $DIR/$tfile >/dev/null
15185
15186         # now data shouldn't be found in the cache
15187         BEFORE=$(roc_hit)
15188         cancel_lru_locks osc
15189         cat $DIR/$tfile >/dev/null
15190         AFTER=$(roc_hit)
15191         if let "AFTER - BEFORE != 0"; then
15192                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15193         fi
15194
15195         set_osd_param $list '' read_cache_enable 1
15196         rm -f $DIR/$tfile
15197 }
15198 run_test 151 "test cache on oss and controls ==============================="
15199
15200 test_152() {
15201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15202
15203         local TF="$TMP/$tfile"
15204
15205         # simulate ENOMEM during write
15206 #define OBD_FAIL_OST_NOMEM      0x226
15207         lctl set_param fail_loc=0x80000226
15208         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15209         cp $TF $DIR/$tfile
15210         sync || error "sync failed"
15211         lctl set_param fail_loc=0
15212
15213         # discard client's cache
15214         cancel_lru_locks osc
15215
15216         # simulate ENOMEM during read
15217         lctl set_param fail_loc=0x80000226
15218         cmp $TF $DIR/$tfile || error "cmp failed"
15219         lctl set_param fail_loc=0
15220
15221         rm -f $TF
15222 }
15223 run_test 152 "test read/write with enomem ============================"
15224
15225 test_153() {
15226         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15227 }
15228 run_test 153 "test if fdatasync does not crash ======================="
15229
15230 dot_lustre_fid_permission_check() {
15231         local fid=$1
15232         local ffid=$MOUNT/.lustre/fid/$fid
15233         local test_dir=$2
15234
15235         echo "stat fid $fid"
15236         stat $ffid > /dev/null || error "stat $ffid failed."
15237         echo "touch fid $fid"
15238         touch $ffid || error "touch $ffid failed."
15239         echo "write to fid $fid"
15240         cat /etc/hosts > $ffid || error "write $ffid failed."
15241         echo "read fid $fid"
15242         diff /etc/hosts $ffid || error "read $ffid failed."
15243         echo "append write to fid $fid"
15244         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15245         echo "rename fid $fid"
15246         mv $ffid $test_dir/$tfile.1 &&
15247                 error "rename $ffid to $tfile.1 should fail."
15248         touch $test_dir/$tfile.1
15249         mv $test_dir/$tfile.1 $ffid &&
15250                 error "rename $tfile.1 to $ffid should fail."
15251         rm -f $test_dir/$tfile.1
15252         echo "truncate fid $fid"
15253         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15254         echo "link fid $fid"
15255         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15256         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15257                 echo "setfacl fid $fid"
15258                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15259                 echo "getfacl fid $fid"
15260                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15261         fi
15262         echo "unlink fid $fid"
15263         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15264         echo "mknod fid $fid"
15265         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15266
15267         fid=[0xf00000400:0x1:0x0]
15268         ffid=$MOUNT/.lustre/fid/$fid
15269
15270         echo "stat non-exist fid $fid"
15271         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15272         echo "write to non-exist fid $fid"
15273         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15274         echo "link new fid $fid"
15275         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15276
15277         mkdir -p $test_dir/$tdir
15278         touch $test_dir/$tdir/$tfile
15279         fid=$($LFS path2fid $test_dir/$tdir)
15280         rc=$?
15281         [ $rc -ne 0 ] &&
15282                 error "error: could not get fid for $test_dir/$dir/$tfile."
15283
15284         ffid=$MOUNT/.lustre/fid/$fid
15285
15286         echo "ls $fid"
15287         ls $ffid > /dev/null || error "ls $ffid failed."
15288         echo "touch $fid/$tfile.1"
15289         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15290
15291         echo "touch $MOUNT/.lustre/fid/$tfile"
15292         touch $MOUNT/.lustre/fid/$tfile && \
15293                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15294
15295         echo "setxattr to $MOUNT/.lustre/fid"
15296         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15297
15298         echo "listxattr for $MOUNT/.lustre/fid"
15299         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15300
15301         echo "delxattr from $MOUNT/.lustre/fid"
15302         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15303
15304         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15305         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15306                 error "touch invalid fid should fail."
15307
15308         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15309         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15310                 error "touch non-normal fid should fail."
15311
15312         echo "rename $tdir to $MOUNT/.lustre/fid"
15313         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15314                 error "rename to $MOUNT/.lustre/fid should fail."
15315
15316         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15317         then            # LU-3547
15318                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15319                 local new_obf_mode=777
15320
15321                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15322                 chmod $new_obf_mode $DIR/.lustre/fid ||
15323                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15324
15325                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15326                 [ $obf_mode -eq $new_obf_mode ] ||
15327                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15328
15329                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15330                 chmod $old_obf_mode $DIR/.lustre/fid ||
15331                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15332         fi
15333
15334         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15335         fid=$($LFS path2fid $test_dir/$tfile-2)
15336
15337         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15338         then # LU-5424
15339                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15340                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15341                         error "create lov data thru .lustre failed"
15342         fi
15343         echo "cp /etc/passwd $test_dir/$tfile-2"
15344         cp /etc/passwd $test_dir/$tfile-2 ||
15345                 error "copy to $test_dir/$tfile-2 failed."
15346         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15347         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15348                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15349
15350         rm -rf $test_dir/tfile.lnk
15351         rm -rf $test_dir/$tfile-2
15352 }
15353
15354 test_154A() {
15355         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15356                 skip "Need MDS version at least 2.4.1"
15357
15358         local tf=$DIR/$tfile
15359         touch $tf
15360
15361         local fid=$($LFS path2fid $tf)
15362         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15363
15364         # check that we get the same pathname back
15365         local rootpath
15366         local found
15367         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15368                 echo "$rootpath $fid"
15369                 found=$($LFS fid2path $rootpath "$fid")
15370                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15371                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15372         done
15373
15374         # check wrong root path format
15375         rootpath=$MOUNT"_wrong"
15376         found=$($LFS fid2path $rootpath "$fid")
15377         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15378 }
15379 run_test 154A "lfs path2fid and fid2path basic checks"
15380
15381 test_154B() {
15382         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15383                 skip "Need MDS version at least 2.4.1"
15384
15385         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15386         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15387         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15388         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15389
15390         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15391         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15392
15393         # check that we get the same pathname
15394         echo "PFID: $PFID, name: $name"
15395         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15396         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15397         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15398                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15399
15400         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15401 }
15402 run_test 154B "verify the ll_decode_linkea tool"
15403
15404 test_154a() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15407         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15408                 skip "Need MDS version at least 2.2.51"
15409         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15410
15411         cp /etc/hosts $DIR/$tfile
15412
15413         fid=$($LFS path2fid $DIR/$tfile)
15414         rc=$?
15415         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15416
15417         dot_lustre_fid_permission_check "$fid" $DIR ||
15418                 error "dot lustre permission check $fid failed"
15419
15420         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15421
15422         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15423
15424         touch $MOUNT/.lustre/file &&
15425                 error "creation is not allowed under .lustre"
15426
15427         mkdir $MOUNT/.lustre/dir &&
15428                 error "mkdir is not allowed under .lustre"
15429
15430         rm -rf $DIR/$tfile
15431 }
15432 run_test 154a "Open-by-FID"
15433
15434 test_154b() {
15435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15436         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15438         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15439                 skip "Need MDS version at least 2.2.51"
15440
15441         local remote_dir=$DIR/$tdir/remote_dir
15442         local MDTIDX=1
15443         local rc=0
15444
15445         mkdir -p $DIR/$tdir
15446         $LFS mkdir -i $MDTIDX $remote_dir ||
15447                 error "create remote directory failed"
15448
15449         cp /etc/hosts $remote_dir/$tfile
15450
15451         fid=$($LFS path2fid $remote_dir/$tfile)
15452         rc=$?
15453         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15454
15455         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15456                 error "dot lustre permission check $fid failed"
15457         rm -rf $DIR/$tdir
15458 }
15459 run_test 154b "Open-by-FID for remote directory"
15460
15461 test_154c() {
15462         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15463                 skip "Need MDS version at least 2.4.1"
15464
15465         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15466         local FID1=$($LFS path2fid $DIR/$tfile.1)
15467         local FID2=$($LFS path2fid $DIR/$tfile.2)
15468         local FID3=$($LFS path2fid $DIR/$tfile.3)
15469
15470         local N=1
15471         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15472                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15473                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15474                 local want=FID$N
15475                 [ "$FID" = "${!want}" ] ||
15476                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15477                 N=$((N + 1))
15478         done
15479
15480         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15481         do
15482                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15483                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15484                 N=$((N + 1))
15485         done
15486 }
15487 run_test 154c "lfs path2fid and fid2path multiple arguments"
15488
15489 test_154d() {
15490         remote_mds_nodsh && skip "remote MDS with nodsh"
15491         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15492                 skip "Need MDS version at least 2.5.53"
15493
15494         if remote_mds; then
15495                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15496         else
15497                 nid="0@lo"
15498         fi
15499         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15500         local fd
15501         local cmd
15502
15503         rm -f $DIR/$tfile
15504         touch $DIR/$tfile
15505
15506         local fid=$($LFS path2fid $DIR/$tfile)
15507         # Open the file
15508         fd=$(free_fd)
15509         cmd="exec $fd<$DIR/$tfile"
15510         eval $cmd
15511         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15512         echo "$fid_list" | grep "$fid"
15513         rc=$?
15514
15515         cmd="exec $fd>/dev/null"
15516         eval $cmd
15517         if [ $rc -ne 0 ]; then
15518                 error "FID $fid not found in open files list $fid_list"
15519         fi
15520 }
15521 run_test 154d "Verify open file fid"
15522
15523 test_154e()
15524 {
15525         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15526                 skip "Need MDS version at least 2.6.50"
15527
15528         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15529                 error ".lustre returned by readdir"
15530         fi
15531 }
15532 run_test 154e ".lustre is not returned by readdir"
15533
15534 test_154f() {
15535         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15536
15537         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15538         mkdir_on_mdt0 $DIR/$tdir
15539         # test dirs inherit from its stripe
15540         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15541         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15542         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15543         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15544         touch $DIR/f
15545
15546         # get fid of parents
15547         local FID0=$($LFS path2fid $DIR/$tdir)
15548         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15549         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15550         local FID3=$($LFS path2fid $DIR)
15551
15552         # check that path2fid --parents returns expected <parent_fid>/name
15553         # 1) test for a directory (single parent)
15554         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15555         [ "$parent" == "$FID0/foo1" ] ||
15556                 error "expected parent: $FID0/foo1, got: $parent"
15557
15558         # 2) test for a file with nlink > 1 (multiple parents)
15559         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15560         echo "$parent" | grep -F "$FID1/$tfile" ||
15561                 error "$FID1/$tfile not returned in parent list"
15562         echo "$parent" | grep -F "$FID2/link" ||
15563                 error "$FID2/link not returned in parent list"
15564
15565         # 3) get parent by fid
15566         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15567         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15568         echo "$parent" | grep -F "$FID1/$tfile" ||
15569                 error "$FID1/$tfile not returned in parent list (by fid)"
15570         echo "$parent" | grep -F "$FID2/link" ||
15571                 error "$FID2/link not returned in parent list (by fid)"
15572
15573         # 4) test for entry in root directory
15574         parent=$($LFS path2fid --parents $DIR/f)
15575         echo "$parent" | grep -F "$FID3/f" ||
15576                 error "$FID3/f not returned in parent list"
15577
15578         # 5) test it on root directory
15579         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15580                 error "$MOUNT should not have parents"
15581
15582         # enable xattr caching and check that linkea is correctly updated
15583         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15584         save_lustre_params client "llite.*.xattr_cache" > $save
15585         lctl set_param llite.*.xattr_cache 1
15586
15587         # 6.1) linkea update on rename
15588         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15589
15590         # get parents by fid
15591         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15592         # foo1 should no longer be returned in parent list
15593         echo "$parent" | grep -F "$FID1" &&
15594                 error "$FID1 should no longer be in parent list"
15595         # the new path should appear
15596         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15597                 error "$FID2/$tfile.moved is not in parent list"
15598
15599         # 6.2) linkea update on unlink
15600         rm -f $DIR/$tdir/foo2/link
15601         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15602         # foo2/link should no longer be returned in parent list
15603         echo "$parent" | grep -F "$FID2/link" &&
15604                 error "$FID2/link should no longer be in parent list"
15605         true
15606
15607         rm -f $DIR/f
15608         restore_lustre_params < $save
15609         rm -f $save
15610 }
15611 run_test 154f "get parent fids by reading link ea"
15612
15613 test_154g()
15614 {
15615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15616         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15617            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15618                 skip "Need MDS version at least 2.6.92"
15619
15620         mkdir_on_mdt0 $DIR/$tdir
15621         llapi_fid_test -d $DIR/$tdir
15622 }
15623 run_test 154g "various llapi FID tests"
15624
15625 test_155_small_load() {
15626     local temp=$TMP/$tfile
15627     local file=$DIR/$tfile
15628
15629     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15630         error "dd of=$temp bs=6096 count=1 failed"
15631     cp $temp $file
15632     cancel_lru_locks $OSC
15633     cmp $temp $file || error "$temp $file differ"
15634
15635     $TRUNCATE $temp 6000
15636     $TRUNCATE $file 6000
15637     cmp $temp $file || error "$temp $file differ (truncate1)"
15638
15639     echo "12345" >>$temp
15640     echo "12345" >>$file
15641     cmp $temp $file || error "$temp $file differ (append1)"
15642
15643     echo "12345" >>$temp
15644     echo "12345" >>$file
15645     cmp $temp $file || error "$temp $file differ (append2)"
15646
15647     rm -f $temp $file
15648     true
15649 }
15650
15651 test_155_big_load() {
15652         remote_ost_nodsh && skip "remote OST with nodsh"
15653
15654         local temp=$TMP/$tfile
15655         local file=$DIR/$tfile
15656
15657         free_min_max
15658         local cache_size=$(do_facet ost$((MAXI+1)) \
15659                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15660
15661         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15662         # pre-set value
15663         if [ -z "$cache_size" ]; then
15664                 cache_size=256
15665         fi
15666         local large_file_size=$((cache_size * 2))
15667
15668         echo "OSS cache size: $cache_size KB"
15669         echo "Large file size: $large_file_size KB"
15670
15671         [ $MAXV -le $large_file_size ] &&
15672                 skip_env "max available OST size needs > $large_file_size KB"
15673
15674         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15675
15676         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15677                 error "dd of=$temp bs=$large_file_size count=1k failed"
15678         cp $temp $file
15679         ls -lh $temp $file
15680         cancel_lru_locks osc
15681         cmp $temp $file || error "$temp $file differ"
15682
15683         rm -f $temp $file
15684         true
15685 }
15686
15687 save_writethrough() {
15688         local facets=$(get_facets OST)
15689
15690         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15691 }
15692
15693 test_155a() {
15694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15695
15696         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15697
15698         save_writethrough $p
15699
15700         set_cache read on
15701         set_cache writethrough on
15702         test_155_small_load
15703         restore_lustre_params < $p
15704         rm -f $p
15705 }
15706 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15707
15708 test_155b() {
15709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15710
15711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15712
15713         save_writethrough $p
15714
15715         set_cache read on
15716         set_cache writethrough off
15717         test_155_small_load
15718         restore_lustre_params < $p
15719         rm -f $p
15720 }
15721 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15722
15723 test_155c() {
15724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15725
15726         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15727
15728         save_writethrough $p
15729
15730         set_cache read off
15731         set_cache writethrough on
15732         test_155_small_load
15733         restore_lustre_params < $p
15734         rm -f $p
15735 }
15736 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15737
15738 test_155d() {
15739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15740
15741         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15742
15743         save_writethrough $p
15744
15745         set_cache read off
15746         set_cache writethrough off
15747         test_155_small_load
15748         restore_lustre_params < $p
15749         rm -f $p
15750 }
15751 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15752
15753 test_155e() {
15754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15755
15756         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15757
15758         save_writethrough $p
15759
15760         set_cache read on
15761         set_cache writethrough on
15762         test_155_big_load
15763         restore_lustre_params < $p
15764         rm -f $p
15765 }
15766 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15767
15768 test_155f() {
15769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15770
15771         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15772
15773         save_writethrough $p
15774
15775         set_cache read on
15776         set_cache writethrough off
15777         test_155_big_load
15778         restore_lustre_params < $p
15779         rm -f $p
15780 }
15781 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15782
15783 test_155g() {
15784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15785
15786         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15787
15788         save_writethrough $p
15789
15790         set_cache read off
15791         set_cache writethrough on
15792         test_155_big_load
15793         restore_lustre_params < $p
15794         rm -f $p
15795 }
15796 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15797
15798 test_155h() {
15799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15800
15801         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15802
15803         save_writethrough $p
15804
15805         set_cache read off
15806         set_cache writethrough off
15807         test_155_big_load
15808         restore_lustre_params < $p
15809         rm -f $p
15810 }
15811 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15812
15813 test_156() {
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         remote_ost_nodsh && skip "remote OST with nodsh"
15816         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15817                 skip "stats not implemented on old servers"
15818         [ "$ost1_FSTYPE" = "zfs" ] &&
15819                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15820
15821         local CPAGES=3
15822         local BEFORE
15823         local AFTER
15824         local file="$DIR/$tfile"
15825         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15826
15827         save_writethrough $p
15828         roc_hit_init
15829
15830         log "Turn on read and write cache"
15831         set_cache read on
15832         set_cache writethrough on
15833
15834         log "Write data and read it back."
15835         log "Read should be satisfied from the cache."
15836         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15837         BEFORE=$(roc_hit)
15838         cancel_lru_locks osc
15839         cat $file >/dev/null
15840         AFTER=$(roc_hit)
15841         if ! let "AFTER - BEFORE == CPAGES"; then
15842                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15843         else
15844                 log "cache hits: before: $BEFORE, after: $AFTER"
15845         fi
15846
15847         log "Read again; it should be satisfied from the cache."
15848         BEFORE=$AFTER
15849         cancel_lru_locks osc
15850         cat $file >/dev/null
15851         AFTER=$(roc_hit)
15852         if ! let "AFTER - BEFORE == CPAGES"; then
15853                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15854         else
15855                 log "cache hits:: before: $BEFORE, after: $AFTER"
15856         fi
15857
15858         log "Turn off the read cache and turn on the write cache"
15859         set_cache read off
15860         set_cache writethrough on
15861
15862         log "Read again; it should be satisfied from the cache."
15863         BEFORE=$(roc_hit)
15864         cancel_lru_locks osc
15865         cat $file >/dev/null
15866         AFTER=$(roc_hit)
15867         if ! let "AFTER - BEFORE == CPAGES"; then
15868                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15869         else
15870                 log "cache hits:: before: $BEFORE, after: $AFTER"
15871         fi
15872
15873         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15874                 # > 2.12.56 uses pagecache if cached
15875                 log "Read again; it should not be satisfied from the cache."
15876                 BEFORE=$AFTER
15877                 cancel_lru_locks osc
15878                 cat $file >/dev/null
15879                 AFTER=$(roc_hit)
15880                 if ! let "AFTER - BEFORE == 0"; then
15881                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15882                 else
15883                         log "cache hits:: before: $BEFORE, after: $AFTER"
15884                 fi
15885         fi
15886
15887         log "Write data and read it back."
15888         log "Read should be satisfied from the cache."
15889         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15890         BEFORE=$(roc_hit)
15891         cancel_lru_locks osc
15892         cat $file >/dev/null
15893         AFTER=$(roc_hit)
15894         if ! let "AFTER - BEFORE == CPAGES"; then
15895                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15896         else
15897                 log "cache hits:: before: $BEFORE, after: $AFTER"
15898         fi
15899
15900         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15901                 # > 2.12.56 uses pagecache if cached
15902                 log "Read again; it should not be satisfied from the cache."
15903                 BEFORE=$AFTER
15904                 cancel_lru_locks osc
15905                 cat $file >/dev/null
15906                 AFTER=$(roc_hit)
15907                 if ! let "AFTER - BEFORE == 0"; then
15908                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15909                 else
15910                         log "cache hits:: before: $BEFORE, after: $AFTER"
15911                 fi
15912         fi
15913
15914         log "Turn off read and write cache"
15915         set_cache read off
15916         set_cache writethrough off
15917
15918         log "Write data and read it back"
15919         log "It should not be satisfied from the cache."
15920         rm -f $file
15921         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15922         cancel_lru_locks osc
15923         BEFORE=$(roc_hit)
15924         cat $file >/dev/null
15925         AFTER=$(roc_hit)
15926         if ! let "AFTER - BEFORE == 0"; then
15927                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15928         else
15929                 log "cache hits:: before: $BEFORE, after: $AFTER"
15930         fi
15931
15932         log "Turn on the read cache and turn off the write cache"
15933         set_cache read on
15934         set_cache writethrough off
15935
15936         log "Write data and read it back"
15937         log "It should not be satisfied from the cache."
15938         rm -f $file
15939         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15940         BEFORE=$(roc_hit)
15941         cancel_lru_locks osc
15942         cat $file >/dev/null
15943         AFTER=$(roc_hit)
15944         if ! let "AFTER - BEFORE == 0"; then
15945                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15946         else
15947                 log "cache hits:: before: $BEFORE, after: $AFTER"
15948         fi
15949
15950         log "Read again; it should be satisfied from the cache."
15951         BEFORE=$(roc_hit)
15952         cancel_lru_locks osc
15953         cat $file >/dev/null
15954         AFTER=$(roc_hit)
15955         if ! let "AFTER - BEFORE == CPAGES"; then
15956                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15957         else
15958                 log "cache hits:: before: $BEFORE, after: $AFTER"
15959         fi
15960
15961         restore_lustre_params < $p
15962         rm -f $p $file
15963 }
15964 run_test 156 "Verification of tunables"
15965
15966 test_160a() {
15967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15968         remote_mds_nodsh && skip "remote MDS with nodsh"
15969         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15970                 skip "Need MDS version at least 2.2.0"
15971
15972         changelog_register || error "changelog_register failed"
15973         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15974         changelog_users $SINGLEMDS | grep -q $cl_user ||
15975                 error "User $cl_user not found in changelog_users"
15976
15977         mkdir_on_mdt0 $DIR/$tdir
15978
15979         # change something
15980         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15981         changelog_clear 0 || error "changelog_clear failed"
15982         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15983         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15984         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15985         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15986         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15987         rm $DIR/$tdir/pics/desktop.jpg
15988
15989         echo "verifying changelog mask"
15990         changelog_chmask "-MKDIR"
15991         changelog_chmask "-CLOSE"
15992
15993         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15994         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15995
15996         changelog_chmask "+MKDIR"
15997         changelog_chmask "+CLOSE"
15998
15999         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16000         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16001
16002         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16003         CLOSES=$(changelog_dump | grep -c "CLOSE")
16004         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16005         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16006
16007         # verify contents
16008         echo "verifying target fid"
16009         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16010         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16011         [ "$fidc" == "$fidf" ] ||
16012                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16013         echo "verifying parent fid"
16014         # The FID returned from the Changelog may be the directory shard on
16015         # a different MDT, and not the FID returned by path2fid on the parent.
16016         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16017         # since this is what will matter when recreating this file in the tree.
16018         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16019         local pathp=$($LFS fid2path $MOUNT "$fidp")
16020         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16021                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16022
16023         echo "getting records for $cl_user"
16024         changelog_users $SINGLEMDS
16025         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16026         local nclr=3
16027         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16028                 error "changelog_clear failed"
16029         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16030         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16031         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16032                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16033
16034         local min0_rec=$(changelog_users $SINGLEMDS |
16035                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16036         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16037                           awk '{ print $1; exit; }')
16038
16039         changelog_dump | tail -n 5
16040         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16041         [ $first_rec == $((min0_rec + 1)) ] ||
16042                 error "first index should be $min0_rec + 1 not $first_rec"
16043
16044         # LU-3446 changelog index reset on MDT restart
16045         local cur_rec1=$(changelog_users $SINGLEMDS |
16046                          awk '/^current.index:/ { print $NF }')
16047         changelog_clear 0 ||
16048                 error "clear all changelog records for $cl_user failed"
16049         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16050         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16051                 error "Fail to start $SINGLEMDS"
16052         local cur_rec2=$(changelog_users $SINGLEMDS |
16053                          awk '/^current.index:/ { print $NF }')
16054         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16055         [ $cur_rec1 == $cur_rec2 ] ||
16056                 error "current index should be $cur_rec1 not $cur_rec2"
16057
16058         echo "verifying users from this test are deregistered"
16059         changelog_deregister || error "changelog_deregister failed"
16060         changelog_users $SINGLEMDS | grep -q $cl_user &&
16061                 error "User '$cl_user' still in changelog_users"
16062
16063         # lctl get_param -n mdd.*.changelog_users
16064         # current_index: 144
16065         # ID    index (idle seconds)
16066         # cl3   144   (2) mask=<list>
16067         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16068                 # this is the normal case where all users were deregistered
16069                 # make sure no new records are added when no users are present
16070                 local last_rec1=$(changelog_users $SINGLEMDS |
16071                                   awk '/^current.index:/ { print $NF }')
16072                 touch $DIR/$tdir/chloe
16073                 local last_rec2=$(changelog_users $SINGLEMDS |
16074                                   awk '/^current.index:/ { print $NF }')
16075                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16076                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16077         else
16078                 # any changelog users must be leftovers from a previous test
16079                 changelog_users $SINGLEMDS
16080                 echo "other changelog users; can't verify off"
16081         fi
16082 }
16083 run_test 160a "changelog sanity"
16084
16085 test_160b() { # LU-3587
16086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16087         remote_mds_nodsh && skip "remote MDS with nodsh"
16088         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16089                 skip "Need MDS version at least 2.2.0"
16090
16091         changelog_register || error "changelog_register failed"
16092         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16093         changelog_users $SINGLEMDS | grep -q $cl_user ||
16094                 error "User '$cl_user' not found in changelog_users"
16095
16096         local longname1=$(str_repeat a 255)
16097         local longname2=$(str_repeat b 255)
16098
16099         cd $DIR
16100         echo "creating very long named file"
16101         touch $longname1 || error "create of '$longname1' failed"
16102         echo "renaming very long named file"
16103         mv $longname1 $longname2
16104
16105         changelog_dump | grep RENME | tail -n 5
16106         rm -f $longname2
16107 }
16108 run_test 160b "Verify that very long rename doesn't crash in changelog"
16109
16110 test_160c() {
16111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16112         remote_mds_nodsh && skip "remote MDS with nodsh"
16113
16114         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16115                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16116                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16117                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16118
16119         local rc=0
16120
16121         # Registration step
16122         changelog_register || error "changelog_register failed"
16123
16124         rm -rf $DIR/$tdir
16125         mkdir -p $DIR/$tdir
16126         $MCREATE $DIR/$tdir/foo_160c
16127         changelog_chmask "-TRUNC"
16128         $TRUNCATE $DIR/$tdir/foo_160c 200
16129         changelog_chmask "+TRUNC"
16130         $TRUNCATE $DIR/$tdir/foo_160c 199
16131         changelog_dump | tail -n 5
16132         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16133         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16134 }
16135 run_test 160c "verify that changelog log catch the truncate event"
16136
16137 test_160d() {
16138         remote_mds_nodsh && skip "remote MDS with nodsh"
16139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16141         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16142                 skip "Need MDS version at least 2.7.60"
16143
16144         # Registration step
16145         changelog_register || error "changelog_register failed"
16146
16147         mkdir -p $DIR/$tdir/migrate_dir
16148         changelog_clear 0 || error "changelog_clear failed"
16149
16150         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16151         changelog_dump | tail -n 5
16152         local migrates=$(changelog_dump | grep -c "MIGRT")
16153         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16154 }
16155 run_test 160d "verify that changelog log catch the migrate event"
16156
16157 test_160e() {
16158         remote_mds_nodsh && skip "remote MDS with nodsh"
16159
16160         # Create a user
16161         changelog_register || error "changelog_register failed"
16162
16163         local MDT0=$(facet_svc $SINGLEMDS)
16164         local rc
16165
16166         # No user (expect fail)
16167         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16168         rc=$?
16169         if [ $rc -eq 0 ]; then
16170                 error "Should fail without user"
16171         elif [ $rc -ne 4 ]; then
16172                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16173         fi
16174
16175         # Delete a future user (expect fail)
16176         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16177         rc=$?
16178         if [ $rc -eq 0 ]; then
16179                 error "Deleted non-existant user cl77"
16180         elif [ $rc -ne 2 ]; then
16181                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16182         fi
16183
16184         # Clear to a bad index (1 billion should be safe)
16185         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16186         rc=$?
16187
16188         if [ $rc -eq 0 ]; then
16189                 error "Successfully cleared to invalid CL index"
16190         elif [ $rc -ne 22 ]; then
16191                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16192         fi
16193 }
16194 run_test 160e "changelog negative testing (should return errors)"
16195
16196 test_160f() {
16197         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16198         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16199                 skip "Need MDS version at least 2.10.56"
16200
16201         local mdts=$(comma_list $(mdts_nodes))
16202
16203         # Create a user
16204         changelog_register || error "first changelog_register failed"
16205         changelog_register || error "second changelog_register failed"
16206         local cl_users
16207         declare -A cl_user1
16208         declare -A cl_user2
16209         local user_rec1
16210         local user_rec2
16211         local i
16212
16213         # generate some changelog records to accumulate on each MDT
16214         # use all_char because created files should be evenly distributed
16215         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16216                 error "test_mkdir $tdir failed"
16217         log "$(date +%s): creating first files"
16218         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16219                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16220                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16221         done
16222
16223         # check changelogs have been generated
16224         local start=$SECONDS
16225         local idle_time=$((MDSCOUNT * 5 + 5))
16226         local nbcl=$(changelog_dump | wc -l)
16227         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16228
16229         for param in "changelog_max_idle_time=$idle_time" \
16230                      "changelog_gc=1" \
16231                      "changelog_min_gc_interval=2" \
16232                      "changelog_min_free_cat_entries=3"; do
16233                 local MDT0=$(facet_svc $SINGLEMDS)
16234                 local var="${param%=*}"
16235                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16236
16237                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16238                 do_nodes $mdts $LCTL set_param mdd.*.$param
16239         done
16240
16241         # force cl_user2 to be idle (1st part), but also cancel the
16242         # cl_user1 records so that it is not evicted later in the test.
16243         local sleep1=$((idle_time / 2))
16244         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16245         sleep $sleep1
16246
16247         # simulate changelog catalog almost full
16248         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16249         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16250
16251         for i in $(seq $MDSCOUNT); do
16252                 cl_users=(${CL_USERS[mds$i]})
16253                 cl_user1[mds$i]="${cl_users[0]}"
16254                 cl_user2[mds$i]="${cl_users[1]}"
16255
16256                 [ -n "${cl_user1[mds$i]}" ] ||
16257                         error "mds$i: no user registered"
16258                 [ -n "${cl_user2[mds$i]}" ] ||
16259                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16260
16261                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16262                 [ -n "$user_rec1" ] ||
16263                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16264                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16265                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16266                 [ -n "$user_rec2" ] ||
16267                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16268                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16269                      "$user_rec1 + 2 == $user_rec2"
16270                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16271                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16272                               "$user_rec1 + 2, but is $user_rec2"
16273                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16274                 [ -n "$user_rec2" ] ||
16275                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16276                 [ $user_rec1 == $user_rec2 ] ||
16277                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16278                               "$user_rec1, but is $user_rec2"
16279         done
16280
16281         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16282         local sleep2=$((idle_time - (SECONDS - start) + 1))
16283         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16284         sleep $sleep2
16285
16286         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16287         # cl_user1 should be OK because it recently processed records.
16288         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16289         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16290                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16291                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16292         done
16293
16294         # ensure gc thread is done
16295         for i in $(mdts_nodes); do
16296                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16297                         error "$i: GC-thread not done"
16298         done
16299
16300         local first_rec
16301         for (( i = 1; i <= MDSCOUNT; i++ )); do
16302                 # check cl_user1 still registered
16303                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16304                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16305                 # check cl_user2 unregistered
16306                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16307                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16308
16309                 # check changelogs are present and starting at $user_rec1 + 1
16310                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16311                 [ -n "$user_rec1" ] ||
16312                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16313                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16314                             awk '{ print $1; exit; }')
16315
16316                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16317                 [ $((user_rec1 + 1)) == $first_rec ] ||
16318                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16319         done
16320 }
16321 run_test 160f "changelog garbage collect (timestamped users)"
16322
16323 test_160g() {
16324         remote_mds_nodsh && skip "remote MDS with nodsh"
16325         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16326                 skip "Need MDS version at least 2.14.55"
16327
16328         local mdts=$(comma_list $(mdts_nodes))
16329
16330         # Create a user
16331         changelog_register || error "first changelog_register failed"
16332         changelog_register || error "second changelog_register failed"
16333         local cl_users
16334         declare -A cl_user1
16335         declare -A cl_user2
16336         local user_rec1
16337         local user_rec2
16338         local i
16339
16340         # generate some changelog records to accumulate on each MDT
16341         # use all_char because created files should be evenly distributed
16342         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16343                 error "test_mkdir $tdir failed"
16344         for ((i = 0; i < MDSCOUNT; i++)); do
16345                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16346                         error "create $DIR/$tdir/d$i.1 failed"
16347         done
16348
16349         # check changelogs have been generated
16350         local nbcl=$(changelog_dump | wc -l)
16351         (( $nbcl > 0 )) || error "no changelogs found"
16352
16353         # reduce the max_idle_indexes value to make sure we exceed it
16354         for param in "changelog_max_idle_indexes=2" \
16355                      "changelog_gc=1" \
16356                      "changelog_min_gc_interval=2"; do
16357                 local MDT0=$(facet_svc $SINGLEMDS)
16358                 local var="${param%=*}"
16359                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16360
16361                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16362                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16363                         error "unable to set mdd.*.$param"
16364         done
16365
16366         local start=$SECONDS
16367         for i in $(seq $MDSCOUNT); do
16368                 cl_users=(${CL_USERS[mds$i]})
16369                 cl_user1[mds$i]="${cl_users[0]}"
16370                 cl_user2[mds$i]="${cl_users[1]}"
16371
16372                 [ -n "${cl_user1[mds$i]}" ] ||
16373                         error "mds$i: user1 is not registered"
16374                 [ -n "${cl_user2[mds$i]}" ] ||
16375                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16376
16377                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16378                 [ -n "$user_rec1" ] ||
16379                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16380                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16381                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16382                 [ -n "$user_rec2" ] ||
16383                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16384                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16385                      "$user_rec1 + 2 == $user_rec2"
16386                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16387                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16388                               "expected $user_rec1 + 2, but is $user_rec2"
16389                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16390                 [ -n "$user_rec2" ] ||
16391                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16392                 [ $user_rec1 == $user_rec2 ] ||
16393                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16394                               "expected $user_rec1, but is $user_rec2"
16395         done
16396
16397         # ensure we are past the previous changelog_min_gc_interval set above
16398         local sleep2=$((start + 2 - SECONDS))
16399         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16400         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16401         # cl_user1 should be OK because it recently processed records.
16402         for ((i = 0; i < MDSCOUNT; i++)); do
16403                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16404                         error "create $DIR/$tdir/d$i.3 failed"
16405         done
16406
16407         # ensure gc thread is done
16408         for i in $(mdts_nodes); do
16409                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16410                         error "$i: GC-thread not done"
16411         done
16412
16413         local first_rec
16414         for (( i = 1; i <= MDSCOUNT; i++ )); do
16415                 # check cl_user1 still registered
16416                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16417                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16418                 # check cl_user2 unregistered
16419                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16420                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16421
16422                 # check changelogs are present and starting at $user_rec1 + 1
16423                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16424                 [ -n "$user_rec1" ] ||
16425                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16426                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16427                             awk '{ print $1; exit; }')
16428
16429                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16430                 [ $((user_rec1 + 1)) == $first_rec ] ||
16431                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16432         done
16433 }
16434 run_test 160g "changelog garbage collect on idle records"
16435
16436 test_160h() {
16437         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16438         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16439                 skip "Need MDS version at least 2.10.56"
16440
16441         local mdts=$(comma_list $(mdts_nodes))
16442
16443         # Create a user
16444         changelog_register || error "first changelog_register failed"
16445         changelog_register || error "second changelog_register failed"
16446         local cl_users
16447         declare -A cl_user1
16448         declare -A cl_user2
16449         local user_rec1
16450         local user_rec2
16451         local i
16452
16453         # generate some changelog records to accumulate on each MDT
16454         # use all_char because created files should be evenly distributed
16455         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16456                 error "test_mkdir $tdir failed"
16457         for ((i = 0; i < MDSCOUNT; i++)); do
16458                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16459                         error "create $DIR/$tdir/d$i.1 failed"
16460         done
16461
16462         # check changelogs have been generated
16463         local nbcl=$(changelog_dump | wc -l)
16464         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16465
16466         for param in "changelog_max_idle_time=10" \
16467                      "changelog_gc=1" \
16468                      "changelog_min_gc_interval=2"; do
16469                 local MDT0=$(facet_svc $SINGLEMDS)
16470                 local var="${param%=*}"
16471                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16472
16473                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16474                 do_nodes $mdts $LCTL set_param mdd.*.$param
16475         done
16476
16477         # force cl_user2 to be idle (1st part)
16478         sleep 9
16479
16480         for i in $(seq $MDSCOUNT); do
16481                 cl_users=(${CL_USERS[mds$i]})
16482                 cl_user1[mds$i]="${cl_users[0]}"
16483                 cl_user2[mds$i]="${cl_users[1]}"
16484
16485                 [ -n "${cl_user1[mds$i]}" ] ||
16486                         error "mds$i: no user registered"
16487                 [ -n "${cl_user2[mds$i]}" ] ||
16488                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16489
16490                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16491                 [ -n "$user_rec1" ] ||
16492                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16493                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16494                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16495                 [ -n "$user_rec2" ] ||
16496                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16497                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16498                      "$user_rec1 + 2 == $user_rec2"
16499                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16500                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16501                               "$user_rec1 + 2, but is $user_rec2"
16502                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16503                 [ -n "$user_rec2" ] ||
16504                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16505                 [ $user_rec1 == $user_rec2 ] ||
16506                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16507                               "$user_rec1, but is $user_rec2"
16508         done
16509
16510         # force cl_user2 to be idle (2nd part) and to reach
16511         # changelog_max_idle_time
16512         sleep 2
16513
16514         # force each GC-thread start and block then
16515         # one per MDT/MDD, set fail_val accordingly
16516         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16517         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16518
16519         # generate more changelogs to trigger fail_loc
16520         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16521                 error "create $DIR/$tdir/${tfile}bis failed"
16522
16523         # stop MDT to stop GC-thread, should be done in back-ground as it will
16524         # block waiting for the thread to be released and exit
16525         declare -A stop_pids
16526         for i in $(seq $MDSCOUNT); do
16527                 stop mds$i &
16528                 stop_pids[mds$i]=$!
16529         done
16530
16531         for i in $(mdts_nodes); do
16532                 local facet
16533                 local nb=0
16534                 local facets=$(facets_up_on_host $i)
16535
16536                 for facet in ${facets//,/ }; do
16537                         if [[ $facet == mds* ]]; then
16538                                 nb=$((nb + 1))
16539                         fi
16540                 done
16541                 # ensure each MDS's gc threads are still present and all in "R"
16542                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16543                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16544                         error "$i: expected $nb GC-thread"
16545                 wait_update $i \
16546                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16547                         "R" 20 ||
16548                         error "$i: GC-thread not found in R-state"
16549                 # check umounts of each MDT on MDS have reached kthread_stop()
16550                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16551                         error "$i: expected $nb umount"
16552                 wait_update $i \
16553                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16554                         error "$i: umount not found in D-state"
16555         done
16556
16557         # release all GC-threads
16558         do_nodes $mdts $LCTL set_param fail_loc=0
16559
16560         # wait for MDT stop to complete
16561         for i in $(seq $MDSCOUNT); do
16562                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16563         done
16564
16565         # XXX
16566         # may try to check if any orphan changelog records are present
16567         # via ldiskfs/zfs and llog_reader...
16568
16569         # re-start/mount MDTs
16570         for i in $(seq $MDSCOUNT); do
16571                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16572                         error "Fail to start mds$i"
16573         done
16574
16575         local first_rec
16576         for i in $(seq $MDSCOUNT); do
16577                 # check cl_user1 still registered
16578                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16579                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16580                 # check cl_user2 unregistered
16581                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16582                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16583
16584                 # check changelogs are present and starting at $user_rec1 + 1
16585                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16586                 [ -n "$user_rec1" ] ||
16587                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16588                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16589                             awk '{ print $1; exit; }')
16590
16591                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16592                 [ $((user_rec1 + 1)) == $first_rec ] ||
16593                         error "mds$i: first index should be $user_rec1 + 1, " \
16594                               "but is $first_rec"
16595         done
16596 }
16597 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16598               "during mount"
16599
16600 test_160i() {
16601
16602         local mdts=$(comma_list $(mdts_nodes))
16603
16604         changelog_register || error "first changelog_register failed"
16605
16606         # generate some changelog records to accumulate on each MDT
16607         # use all_char because created files should be evenly distributed
16608         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16609                 error "test_mkdir $tdir failed"
16610         for ((i = 0; i < MDSCOUNT; i++)); do
16611                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16612                         error "create $DIR/$tdir/d$i.1 failed"
16613         done
16614
16615         # check changelogs have been generated
16616         local nbcl=$(changelog_dump | wc -l)
16617         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16618
16619         # simulate race between register and unregister
16620         # XXX as fail_loc is set per-MDS, with DNE configs the race
16621         # simulation will only occur for one MDT per MDS and for the
16622         # others the normal race scenario will take place
16623         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16624         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16625         do_nodes $mdts $LCTL set_param fail_val=1
16626
16627         # unregister 1st user
16628         changelog_deregister &
16629         local pid1=$!
16630         # wait some time for deregister work to reach race rdv
16631         sleep 2
16632         # register 2nd user
16633         changelog_register || error "2nd user register failed"
16634
16635         wait $pid1 || error "1st user deregister failed"
16636
16637         local i
16638         local last_rec
16639         declare -A LAST_REC
16640         for i in $(seq $MDSCOUNT); do
16641                 if changelog_users mds$i | grep "^cl"; then
16642                         # make sure new records are added with one user present
16643                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16644                                           awk '/^current.index:/ { print $NF }')
16645                 else
16646                         error "mds$i has no user registered"
16647                 fi
16648         done
16649
16650         # generate more changelog records to accumulate on each MDT
16651         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16652                 error "create $DIR/$tdir/${tfile}bis failed"
16653
16654         for i in $(seq $MDSCOUNT); do
16655                 last_rec=$(changelog_users $SINGLEMDS |
16656                            awk '/^current.index:/ { print $NF }')
16657                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16658                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16659                         error "changelogs are off on mds$i"
16660         done
16661 }
16662 run_test 160i "changelog user register/unregister race"
16663
16664 test_160j() {
16665         remote_mds_nodsh && skip "remote MDS with nodsh"
16666         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16667                 skip "Need MDS version at least 2.12.56"
16668
16669         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16670         stack_trap "umount $MOUNT2" EXIT
16671
16672         changelog_register || error "first changelog_register failed"
16673         stack_trap "changelog_deregister" EXIT
16674
16675         # generate some changelog
16676         # use all_char because created files should be evenly distributed
16677         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16678                 error "mkdir $tdir failed"
16679         for ((i = 0; i < MDSCOUNT; i++)); do
16680                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16681                         error "create $DIR/$tdir/d$i.1 failed"
16682         done
16683
16684         # open the changelog device
16685         exec 3>/dev/changelog-$FSNAME-MDT0000
16686         stack_trap "exec 3>&-" EXIT
16687         exec 4</dev/changelog-$FSNAME-MDT0000
16688         stack_trap "exec 4<&-" EXIT
16689
16690         # umount the first lustre mount
16691         umount $MOUNT
16692         stack_trap "mount_client $MOUNT" EXIT
16693
16694         # read changelog, which may or may not fail, but should not crash
16695         cat <&4 >/dev/null
16696
16697         # clear changelog
16698         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16699         changelog_users $SINGLEMDS | grep -q $cl_user ||
16700                 error "User $cl_user not found in changelog_users"
16701
16702         printf 'clear:'$cl_user':0' >&3
16703 }
16704 run_test 160j "client can be umounted while its chanangelog is being used"
16705
16706 test_160k() {
16707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16708         remote_mds_nodsh && skip "remote MDS with nodsh"
16709
16710         mkdir -p $DIR/$tdir/1/1
16711
16712         changelog_register || error "changelog_register failed"
16713         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16714
16715         changelog_users $SINGLEMDS | grep -q $cl_user ||
16716                 error "User '$cl_user' not found in changelog_users"
16717 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16718         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16719         rmdir $DIR/$tdir/1/1 & sleep 1
16720         mkdir $DIR/$tdir/2
16721         touch $DIR/$tdir/2/2
16722         rm -rf $DIR/$tdir/2
16723
16724         wait
16725         sleep 4
16726
16727         changelog_dump | grep rmdir || error "rmdir not recorded"
16728 }
16729 run_test 160k "Verify that changelog records are not lost"
16730
16731 # Verifies that a file passed as a parameter has recently had an operation
16732 # performed on it that has generated an MTIME changelog which contains the
16733 # correct parent FID. As files might reside on a different MDT from the
16734 # parent directory in DNE configurations, the FIDs are translated to paths
16735 # before being compared, which should be identical
16736 compare_mtime_changelog() {
16737         local file="${1}"
16738         local mdtidx
16739         local mtime
16740         local cl_fid
16741         local pdir
16742         local dir
16743
16744         mdtidx=$($LFS getstripe --mdt-index $file)
16745         mdtidx=$(printf "%04x" $mdtidx)
16746
16747         # Obtain the parent FID from the MTIME changelog
16748         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16749         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16750
16751         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16752         [ -z "$cl_fid" ] && error "parent FID not present"
16753
16754         # Verify that the path for the parent FID is the same as the path for
16755         # the test directory
16756         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16757
16758         dir=$(dirname $1)
16759
16760         [[ "${pdir%/}" == "$dir" ]] ||
16761                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16762 }
16763
16764 test_160l() {
16765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16766
16767         remote_mds_nodsh && skip "remote MDS with nodsh"
16768         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16769                 skip "Need MDS version at least 2.13.55"
16770
16771         local cl_user
16772
16773         changelog_register || error "changelog_register failed"
16774         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16775
16776         changelog_users $SINGLEMDS | grep -q $cl_user ||
16777                 error "User '$cl_user' not found in changelog_users"
16778
16779         # Clear some types so that MTIME changelogs are generated
16780         changelog_chmask "-CREAT"
16781         changelog_chmask "-CLOSE"
16782
16783         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16784
16785         # Test CL_MTIME during setattr
16786         touch $DIR/$tdir/$tfile
16787         compare_mtime_changelog $DIR/$tdir/$tfile
16788
16789         # Test CL_MTIME during close
16790         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16791         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16792 }
16793 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16794
16795 test_160m() {
16796         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16797         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16798                 skip "Need MDS version at least 2.14.51"
16799         local cl_users
16800         local cl_user1
16801         local cl_user2
16802         local pid1
16803
16804         # Create a user
16805         changelog_register || error "first changelog_register failed"
16806         changelog_register || error "second changelog_register failed"
16807
16808         cl_users=(${CL_USERS[mds1]})
16809         cl_user1="${cl_users[0]}"
16810         cl_user2="${cl_users[1]}"
16811         # generate some changelog records to accumulate on MDT0
16812         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16813         createmany -m $DIR/$tdir/$tfile 50 ||
16814                 error "create $DIR/$tdir/$tfile failed"
16815         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16816         rm -f $DIR/$tdir
16817
16818         # check changelogs have been generated
16819         local nbcl=$(changelog_dump | wc -l)
16820         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16821
16822 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16823         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16824
16825         __changelog_clear mds1 $cl_user1 +10
16826         __changelog_clear mds1 $cl_user2 0 &
16827         pid1=$!
16828         sleep 2
16829         __changelog_clear mds1 $cl_user1 0 ||
16830                 error "fail to cancel record for $cl_user1"
16831         wait $pid1
16832         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16833 }
16834 run_test 160m "Changelog clear race"
16835
16836 test_160n() {
16837         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16838         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16839                 skip "Need MDS version at least 2.14.51"
16840         local cl_users
16841         local cl_user1
16842         local cl_user2
16843         local pid1
16844         local first_rec
16845         local last_rec=0
16846
16847         # Create a user
16848         changelog_register || error "first changelog_register failed"
16849
16850         cl_users=(${CL_USERS[mds1]})
16851         cl_user1="${cl_users[0]}"
16852
16853         # generate some changelog records to accumulate on MDT0
16854         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16855         first_rec=$(changelog_users $SINGLEMDS |
16856                         awk '/^current.index:/ { print $NF }')
16857         while (( last_rec < (( first_rec + 65000)) )); do
16858                 createmany -m $DIR/$tdir/$tfile 10000 ||
16859                         error "create $DIR/$tdir/$tfile failed"
16860
16861                 for i in $(seq 0 10000); do
16862                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16863                                 > /dev/null
16864                 done
16865
16866                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16867                         error "unlinkmany failed unlink"
16868                 last_rec=$(changelog_users $SINGLEMDS |
16869                         awk '/^current.index:/ { print $NF }')
16870                 echo last record $last_rec
16871                 (( last_rec == 0 )) && error "no changelog found"
16872         done
16873
16874 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16875         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16876
16877         __changelog_clear mds1 $cl_user1 0 &
16878         pid1=$!
16879         sleep 2
16880         __changelog_clear mds1 $cl_user1 0 ||
16881                 error "fail to cancel record for $cl_user1"
16882         wait $pid1
16883         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16884 }
16885 run_test 160n "Changelog destroy race"
16886
16887 test_160o() {
16888         local mdt="$(facet_svc $SINGLEMDS)"
16889
16890         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16891         remote_mds_nodsh && skip "remote MDS with nodsh"
16892         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16893                 skip "Need MDS version at least 2.14.52"
16894
16895         changelog_register --user test_160o -m unlnk+close+open ||
16896                 error "changelog_register failed"
16897
16898         do_facet $SINGLEMDS $LCTL --device $mdt \
16899                                 changelog_register -u "Tt3_-#" &&
16900                 error "bad symbols in name should fail"
16901
16902         do_facet $SINGLEMDS $LCTL --device $mdt \
16903                                 changelog_register -u test_160o &&
16904                 error "the same name registration should fail"
16905
16906         do_facet $SINGLEMDS $LCTL --device $mdt \
16907                         changelog_register -u test_160toolongname &&
16908                 error "too long name registration should fail"
16909
16910         changelog_chmask "MARK+HSM"
16911         lctl get_param mdd.*.changelog*mask
16912         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16913         changelog_users $SINGLEMDS | grep -q $cl_user ||
16914                 error "User $cl_user not found in changelog_users"
16915         #verify username
16916         echo $cl_user | grep -q test_160o ||
16917                 error "User $cl_user has no specific name 'test160o'"
16918
16919         # change something
16920         changelog_clear 0 || error "changelog_clear failed"
16921         # generate some changelog records to accumulate on MDT0
16922         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16923         touch $DIR/$tdir/$tfile                 # open 1
16924
16925         OPENS=$(changelog_dump | grep -c "OPEN")
16926         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16927
16928         # must be no MKDIR it wasn't set as user mask
16929         MKDIR=$(changelog_dump | grep -c "MKDIR")
16930         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16931
16932         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16933                                 mdd.$mdt.changelog_current_mask -n)
16934         # register maskless user
16935         changelog_register || error "changelog_register failed"
16936         # effective mask should be not changed because it is not minimal
16937         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16938                                 mdd.$mdt.changelog_current_mask -n)
16939         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16940         # set server mask to minimal value
16941         changelog_chmask "MARK"
16942         # check effective mask again, should be treated as DEFMASK now
16943         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16944                                 mdd.$mdt.changelog_current_mask -n)
16945         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16946
16947         do_facet $SINGLEMDS $LCTL --device $mdt \
16948                                 changelog_deregister -u test_160o ||
16949                 error "cannot deregister by name"
16950 }
16951 run_test 160o "changelog user name and mask"
16952
16953 test_160p() {
16954         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16955         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16956                 skip "Need MDS version at least 2.14.51"
16957         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16958         local cl_users
16959         local cl_user1
16960         local entry_count
16961
16962         # Create a user
16963         changelog_register || error "first changelog_register failed"
16964
16965         cl_users=(${CL_USERS[mds1]})
16966         cl_user1="${cl_users[0]}"
16967
16968         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16969         createmany -m $DIR/$tdir/$tfile 50 ||
16970                 error "create $DIR/$tdir/$tfile failed"
16971         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16972         rm -rf $DIR/$tdir
16973
16974         # check changelogs have been generated
16975         entry_count=$(changelog_dump | wc -l)
16976         ((entry_count != 0)) || error "no changelog entries found"
16977
16978         # remove changelog_users and check that orphan entries are removed
16979         stop mds1
16980         local dev=$(mdsdevname 1)
16981         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16982         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16983         entry_count=$(changelog_dump | wc -l)
16984         ((entry_count == 0)) ||
16985                 error "found $entry_count changelog entries, expected none"
16986 }
16987 run_test 160p "Changelog orphan cleanup with no users"
16988
16989 test_160q() {
16990         local mdt="$(facet_svc $SINGLEMDS)"
16991         local clu
16992
16993         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16994         remote_mds_nodsh && skip "remote MDS with nodsh"
16995         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16996                 skip "Need MDS version at least 2.14.54"
16997
16998         # set server mask to minimal value like server init does
16999         changelog_chmask "MARK"
17000         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17001                 error "changelog_register failed"
17002         # check effective mask again, should be treated as DEFMASK now
17003         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17004                                 mdd.$mdt.changelog_current_mask -n)
17005         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17006                 error "changelog_deregister failed"
17007         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17008 }
17009 run_test 160q "changelog effective mask is DEFMASK if not set"
17010
17011 test_160s() {
17012         remote_mds_nodsh && skip "remote MDS with nodsh"
17013         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17014                 skip "Need MDS version at least 2.14.55"
17015
17016         local mdts=$(comma_list $(mdts_nodes))
17017
17018         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17019         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17020                                        fail_val=$((24 * 3600 * 10))
17021
17022         # Create a user which is 10 days old
17023         changelog_register || error "first changelog_register failed"
17024         local cl_users
17025         declare -A cl_user1
17026         local i
17027
17028         # generate some changelog records to accumulate on each MDT
17029         # use all_char because created files should be evenly distributed
17030         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17031                 error "test_mkdir $tdir failed"
17032         for ((i = 0; i < MDSCOUNT; i++)); do
17033                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17034                         error "create $DIR/$tdir/d$i.1 failed"
17035         done
17036
17037         # check changelogs have been generated
17038         local nbcl=$(changelog_dump | wc -l)
17039         (( nbcl > 0 )) || error "no changelogs found"
17040
17041         # reduce the max_idle_indexes value to make sure we exceed it
17042         for param in "changelog_max_idle_indexes=2097446912" \
17043                      "changelog_max_idle_time=2592000" \
17044                      "changelog_gc=1" \
17045                      "changelog_min_gc_interval=2"; do
17046                 local MDT0=$(facet_svc $SINGLEMDS)
17047                 local var="${param%=*}"
17048                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17049
17050                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17051                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17052                         error "unable to set mdd.*.$param"
17053         done
17054
17055         local start=$SECONDS
17056         for i in $(seq $MDSCOUNT); do
17057                 cl_users=(${CL_USERS[mds$i]})
17058                 cl_user1[mds$i]="${cl_users[0]}"
17059
17060                 [[ -n "${cl_user1[mds$i]}" ]] ||
17061                         error "mds$i: no user registered"
17062         done
17063
17064         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17065         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17066
17067         # ensure we are past the previous changelog_min_gc_interval set above
17068         local sleep2=$((start + 2 - SECONDS))
17069         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17070
17071         # Generate one more changelog to trigger GC
17072         for ((i = 0; i < MDSCOUNT; i++)); do
17073                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17074                         error "create $DIR/$tdir/d$i.3 failed"
17075         done
17076
17077         # ensure gc thread is done
17078         for node in $(mdts_nodes); do
17079                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17080                         error "$node: GC-thread not done"
17081         done
17082
17083         do_nodes $mdts $LCTL set_param fail_loc=0
17084
17085         for (( i = 1; i <= MDSCOUNT; i++ )); do
17086                 # check cl_user1 is purged
17087                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17088                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17089         done
17090         return 0
17091 }
17092 run_test 160s "changelog garbage collect on idle records * time"
17093
17094 test_161a() {
17095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17096
17097         test_mkdir -c1 $DIR/$tdir
17098         cp /etc/hosts $DIR/$tdir/$tfile
17099         test_mkdir -c1 $DIR/$tdir/foo1
17100         test_mkdir -c1 $DIR/$tdir/foo2
17101         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17102         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17103         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17104         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17105         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17106         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17107                 $LFS fid2path $DIR $FID
17108                 error "bad link ea"
17109         fi
17110         # middle
17111         rm $DIR/$tdir/foo2/zachary
17112         # last
17113         rm $DIR/$tdir/foo2/thor
17114         # first
17115         rm $DIR/$tdir/$tfile
17116         # rename
17117         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17118         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17119                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17120         rm $DIR/$tdir/foo2/maggie
17121
17122         # overflow the EA
17123         local longname=$tfile.avg_len_is_thirty_two_
17124         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17125                 error_noexit 'failed to unlink many hardlinks'" EXIT
17126         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17127                 error "failed to hardlink many files"
17128         links=$($LFS fid2path $DIR $FID | wc -l)
17129         echo -n "${links}/1000 links in link EA"
17130         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17131 }
17132 run_test 161a "link ea sanity"
17133
17134 test_161b() {
17135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17136         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17137
17138         local MDTIDX=1
17139         local remote_dir=$DIR/$tdir/remote_dir
17140
17141         mkdir -p $DIR/$tdir
17142         $LFS mkdir -i $MDTIDX $remote_dir ||
17143                 error "create remote directory failed"
17144
17145         cp /etc/hosts $remote_dir/$tfile
17146         mkdir -p $remote_dir/foo1
17147         mkdir -p $remote_dir/foo2
17148         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17149         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17150         ln $remote_dir/$tfile $remote_dir/foo1/luna
17151         ln $remote_dir/$tfile $remote_dir/foo2/thor
17152
17153         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17154                      tr -d ']')
17155         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17156                 $LFS fid2path $DIR $FID
17157                 error "bad link ea"
17158         fi
17159         # middle
17160         rm $remote_dir/foo2/zachary
17161         # last
17162         rm $remote_dir/foo2/thor
17163         # first
17164         rm $remote_dir/$tfile
17165         # rename
17166         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17167         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17168         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17169                 $LFS fid2path $DIR $FID
17170                 error "bad link rename"
17171         fi
17172         rm $remote_dir/foo2/maggie
17173
17174         # overflow the EA
17175         local longname=filename_avg_len_is_thirty_two_
17176         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17177                 error "failed to hardlink many files"
17178         links=$($LFS fid2path $DIR $FID | wc -l)
17179         echo -n "${links}/1000 links in link EA"
17180         [[ ${links} -gt 60 ]] ||
17181                 error "expected at least 60 links in link EA"
17182         unlinkmany $remote_dir/foo2/$longname 1000 ||
17183         error "failed to unlink many hardlinks"
17184 }
17185 run_test 161b "link ea sanity under remote directory"
17186
17187 test_161c() {
17188         remote_mds_nodsh && skip "remote MDS with nodsh"
17189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17190         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17191                 skip "Need MDS version at least 2.1.5"
17192
17193         # define CLF_RENAME_LAST 0x0001
17194         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17195         changelog_register || error "changelog_register failed"
17196
17197         rm -rf $DIR/$tdir
17198         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17199         touch $DIR/$tdir/foo_161c
17200         touch $DIR/$tdir/bar_161c
17201         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17202         changelog_dump | grep RENME | tail -n 5
17203         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17204         changelog_clear 0 || error "changelog_clear failed"
17205         if [ x$flags != "x0x1" ]; then
17206                 error "flag $flags is not 0x1"
17207         fi
17208
17209         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17210         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17211         touch $DIR/$tdir/foo_161c
17212         touch $DIR/$tdir/bar_161c
17213         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17214         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17215         changelog_dump | grep RENME | tail -n 5
17216         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17217         changelog_clear 0 || error "changelog_clear failed"
17218         if [ x$flags != "x0x0" ]; then
17219                 error "flag $flags is not 0x0"
17220         fi
17221         echo "rename overwrite a target having nlink > 1," \
17222                 "changelog record has flags of $flags"
17223
17224         # rename doesn't overwrite a target (changelog flag 0x0)
17225         touch $DIR/$tdir/foo_161c
17226         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17227         changelog_dump | grep RENME | tail -n 5
17228         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17229         changelog_clear 0 || error "changelog_clear failed"
17230         if [ x$flags != "x0x0" ]; then
17231                 error "flag $flags is not 0x0"
17232         fi
17233         echo "rename doesn't overwrite a target," \
17234                 "changelog record has flags of $flags"
17235
17236         # define CLF_UNLINK_LAST 0x0001
17237         # unlink a file having nlink = 1 (changelog flag 0x1)
17238         rm -f $DIR/$tdir/foo2_161c
17239         changelog_dump | grep UNLNK | tail -n 5
17240         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17241         changelog_clear 0 || error "changelog_clear failed"
17242         if [ x$flags != "x0x1" ]; then
17243                 error "flag $flags is not 0x1"
17244         fi
17245         echo "unlink a file having nlink = 1," \
17246                 "changelog record has flags of $flags"
17247
17248         # unlink a file having nlink > 1 (changelog flag 0x0)
17249         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17250         rm -f $DIR/$tdir/foobar_161c
17251         changelog_dump | grep UNLNK | tail -n 5
17252         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17253         changelog_clear 0 || error "changelog_clear failed"
17254         if [ x$flags != "x0x0" ]; then
17255                 error "flag $flags is not 0x0"
17256         fi
17257         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17258 }
17259 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17260
17261 test_161d() {
17262         remote_mds_nodsh && skip "remote MDS with nodsh"
17263         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17264
17265         local pid
17266         local fid
17267
17268         changelog_register || error "changelog_register failed"
17269
17270         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17271         # interfer with $MOUNT/.lustre/fid/ access
17272         mkdir $DIR/$tdir
17273         [[ $? -eq 0 ]] || error "mkdir failed"
17274
17275         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17276         $LCTL set_param fail_loc=0x8000140c
17277         # 5s pause
17278         $LCTL set_param fail_val=5
17279
17280         # create file
17281         echo foofoo > $DIR/$tdir/$tfile &
17282         pid=$!
17283
17284         # wait for create to be delayed
17285         sleep 2
17286
17287         ps -p $pid
17288         [[ $? -eq 0 ]] || error "create should be blocked"
17289
17290         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17291         stack_trap "rm -f $tempfile"
17292         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17293         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17294         # some delay may occur during ChangeLog publishing and file read just
17295         # above, that could allow file write to happen finally
17296         [[ -s $tempfile ]] && echo "file should be empty"
17297
17298         $LCTL set_param fail_loc=0
17299
17300         wait $pid
17301         [[ $? -eq 0 ]] || error "create failed"
17302 }
17303 run_test 161d "create with concurrent .lustre/fid access"
17304
17305 check_path() {
17306         local expected="$1"
17307         shift
17308         local fid="$2"
17309
17310         local path
17311         path=$($LFS fid2path "$@")
17312         local rc=$?
17313
17314         if [ $rc -ne 0 ]; then
17315                 error "path looked up of '$expected' failed: rc=$rc"
17316         elif [ "$path" != "$expected" ]; then
17317                 error "path looked up '$path' instead of '$expected'"
17318         else
17319                 echo "FID '$fid' resolves to path '$path' as expected"
17320         fi
17321 }
17322
17323 test_162a() { # was test_162
17324         test_mkdir -p -c1 $DIR/$tdir/d2
17325         touch $DIR/$tdir/d2/$tfile
17326         touch $DIR/$tdir/d2/x1
17327         touch $DIR/$tdir/d2/x2
17328         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17329         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17330         # regular file
17331         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17332         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17333
17334         # softlink
17335         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17336         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17337         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17338
17339         # softlink to wrong file
17340         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17341         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17342         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17343
17344         # hardlink
17345         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17346         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17347         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17348         # fid2path dir/fsname should both work
17349         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17350         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17351
17352         # hardlink count: check that there are 2 links
17353         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17354         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17355
17356         # hardlink indexing: remove the first link
17357         rm $DIR/$tdir/d2/p/q/r/hlink
17358         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17359 }
17360 run_test 162a "path lookup sanity"
17361
17362 test_162b() {
17363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17365
17366         mkdir $DIR/$tdir
17367         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17368                                 error "create striped dir failed"
17369
17370         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17371                                         tail -n 1 | awk '{print $2}')
17372         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17373
17374         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17375         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17376
17377         # regular file
17378         for ((i=0;i<5;i++)); do
17379                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17380                         error "get fid for f$i failed"
17381                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17382
17383                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17384                         error "get fid for d$i failed"
17385                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17386         done
17387
17388         return 0
17389 }
17390 run_test 162b "striped directory path lookup sanity"
17391
17392 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17393 test_162c() {
17394         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17395                 skip "Need MDS version at least 2.7.51"
17396
17397         local lpath=$tdir.local
17398         local rpath=$tdir.remote
17399
17400         test_mkdir $DIR/$lpath
17401         test_mkdir $DIR/$rpath
17402
17403         for ((i = 0; i <= 101; i++)); do
17404                 lpath="$lpath/$i"
17405                 mkdir $DIR/$lpath
17406                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17407                         error "get fid for local directory $DIR/$lpath failed"
17408                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17409
17410                 rpath="$rpath/$i"
17411                 test_mkdir $DIR/$rpath
17412                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17413                         error "get fid for remote directory $DIR/$rpath failed"
17414                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17415         done
17416
17417         return 0
17418 }
17419 run_test 162c "fid2path works with paths 100 or more directories deep"
17420
17421 oalr_event_count() {
17422         local event="${1}"
17423         local trace="${2}"
17424
17425         awk -v name="${FSNAME}-OST0000" \
17426             -v event="${event}" \
17427             '$1 == "TRACE" && $2 == event && $3 == name' \
17428             "${trace}" |
17429         wc -l
17430 }
17431
17432 oalr_expect_event_count() {
17433         local event="${1}"
17434         local trace="${2}"
17435         local expect="${3}"
17436         local count
17437
17438         count=$(oalr_event_count "${event}" "${trace}")
17439         if ((count == expect)); then
17440                 return 0
17441         fi
17442
17443         error_noexit "${event} event count was '${count}', expected ${expect}"
17444         cat "${trace}" >&2
17445         exit 1
17446 }
17447
17448 cleanup_165() {
17449         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17450         stop ost1
17451         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17452 }
17453
17454 setup_165() {
17455         sync # Flush previous IOs so we can count log entries.
17456         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17457         stack_trap cleanup_165 EXIT
17458 }
17459
17460 test_165a() {
17461         local trace="/tmp/${tfile}.trace"
17462         local rc
17463         local count
17464
17465         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17466                 skip "OFD access log unsupported"
17467
17468         setup_165
17469         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17470         sleep 5
17471
17472         do_facet ost1 ofd_access_log_reader --list
17473         stop ost1
17474
17475         do_facet ost1 killall -TERM ofd_access_log_reader
17476         wait
17477         rc=$?
17478
17479         if ((rc != 0)); then
17480                 error "ofd_access_log_reader exited with rc = '${rc}'"
17481         fi
17482
17483         # Parse trace file for discovery events:
17484         oalr_expect_event_count alr_log_add "${trace}" 1
17485         oalr_expect_event_count alr_log_eof "${trace}" 1
17486         oalr_expect_event_count alr_log_free "${trace}" 1
17487 }
17488 run_test 165a "ofd access log discovery"
17489
17490 test_165b() {
17491         local trace="/tmp/${tfile}.trace"
17492         local file="${DIR}/${tfile}"
17493         local pfid1
17494         local pfid2
17495         local -a entry
17496         local rc
17497         local count
17498         local size
17499         local flags
17500
17501         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17502                 skip "OFD access log unsupported"
17503
17504         setup_165
17505         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17506         sleep 5
17507
17508         do_facet ost1 ofd_access_log_reader --list
17509
17510         lfs setstripe -c 1 -i 0 "${file}"
17511         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17512                 error "cannot create '${file}'"
17513
17514         sleep 5
17515         do_facet ost1 killall -TERM ofd_access_log_reader
17516         wait
17517         rc=$?
17518
17519         if ((rc != 0)); then
17520                 error "ofd_access_log_reader exited with rc = '${rc}'"
17521         fi
17522
17523         oalr_expect_event_count alr_log_entry "${trace}" 1
17524
17525         pfid1=$($LFS path2fid "${file}")
17526
17527         # 1     2             3   4    5     6   7    8    9     10
17528         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17529         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17530
17531         echo "entry = '${entry[*]}'" >&2
17532
17533         pfid2=${entry[4]}
17534         if [[ "${pfid1}" != "${pfid2}" ]]; then
17535                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17536         fi
17537
17538         size=${entry[8]}
17539         if ((size != 1048576)); then
17540                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17541         fi
17542
17543         flags=${entry[10]}
17544         if [[ "${flags}" != "w" ]]; then
17545                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17546         fi
17547
17548         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17549         sleep 5
17550
17551         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17552                 error "cannot read '${file}'"
17553         sleep 5
17554
17555         do_facet ost1 killall -TERM ofd_access_log_reader
17556         wait
17557         rc=$?
17558
17559         if ((rc != 0)); then
17560                 error "ofd_access_log_reader exited with rc = '${rc}'"
17561         fi
17562
17563         oalr_expect_event_count alr_log_entry "${trace}" 1
17564
17565         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17566         echo "entry = '${entry[*]}'" >&2
17567
17568         pfid2=${entry[4]}
17569         if [[ "${pfid1}" != "${pfid2}" ]]; then
17570                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17571         fi
17572
17573         size=${entry[8]}
17574         if ((size != 524288)); then
17575                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17576         fi
17577
17578         flags=${entry[10]}
17579         if [[ "${flags}" != "r" ]]; then
17580                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17581         fi
17582 }
17583 run_test 165b "ofd access log entries are produced and consumed"
17584
17585 test_165c() {
17586         local trace="/tmp/${tfile}.trace"
17587         local file="${DIR}/${tdir}/${tfile}"
17588
17589         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17590                 skip "OFD access log unsupported"
17591
17592         test_mkdir "${DIR}/${tdir}"
17593
17594         setup_165
17595         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17596         sleep 5
17597
17598         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17599
17600         # 4096 / 64 = 64. Create twice as many entries.
17601         for ((i = 0; i < 128; i++)); do
17602                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17603                         error "cannot create file"
17604         done
17605
17606         sync
17607
17608         do_facet ost1 killall -TERM ofd_access_log_reader
17609         wait
17610         rc=$?
17611         if ((rc != 0)); then
17612                 error "ofd_access_log_reader exited with rc = '${rc}'"
17613         fi
17614
17615         unlinkmany  "${file}-%d" 128
17616 }
17617 run_test 165c "full ofd access logs do not block IOs"
17618
17619 oal_get_read_count() {
17620         local stats="$1"
17621
17622         # STATS lustre-OST0001 alr_read_count 1
17623
17624         do_facet ost1 cat "${stats}" |
17625         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17626              END { print count; }'
17627 }
17628
17629 oal_expect_read_count() {
17630         local stats="$1"
17631         local count
17632         local expect="$2"
17633
17634         # Ask ofd_access_log_reader to write stats.
17635         do_facet ost1 killall -USR1 ofd_access_log_reader
17636
17637         # Allow some time for things to happen.
17638         sleep 1
17639
17640         count=$(oal_get_read_count "${stats}")
17641         if ((count == expect)); then
17642                 return 0
17643         fi
17644
17645         error_noexit "bad read count, got ${count}, expected ${expect}"
17646         do_facet ost1 cat "${stats}" >&2
17647         exit 1
17648 }
17649
17650 test_165d() {
17651         local stats="/tmp/${tfile}.stats"
17652         local file="${DIR}/${tdir}/${tfile}"
17653         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17654
17655         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17656                 skip "OFD access log unsupported"
17657
17658         test_mkdir "${DIR}/${tdir}"
17659
17660         setup_165
17661         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17662         sleep 5
17663
17664         lfs setstripe -c 1 -i 0 "${file}"
17665
17666         do_facet ost1 lctl set_param "${param}=rw"
17667         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17668                 error "cannot create '${file}'"
17669         oal_expect_read_count "${stats}" 1
17670
17671         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17672                 error "cannot read '${file}'"
17673         oal_expect_read_count "${stats}" 2
17674
17675         do_facet ost1 lctl set_param "${param}=r"
17676         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17677                 error "cannot create '${file}'"
17678         oal_expect_read_count "${stats}" 2
17679
17680         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17681                 error "cannot read '${file}'"
17682         oal_expect_read_count "${stats}" 3
17683
17684         do_facet ost1 lctl set_param "${param}=w"
17685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17686                 error "cannot create '${file}'"
17687         oal_expect_read_count "${stats}" 4
17688
17689         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17690                 error "cannot read '${file}'"
17691         oal_expect_read_count "${stats}" 4
17692
17693         do_facet ost1 lctl set_param "${param}=0"
17694         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17695                 error "cannot create '${file}'"
17696         oal_expect_read_count "${stats}" 4
17697
17698         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17699                 error "cannot read '${file}'"
17700         oal_expect_read_count "${stats}" 4
17701
17702         do_facet ost1 killall -TERM ofd_access_log_reader
17703         wait
17704         rc=$?
17705         if ((rc != 0)); then
17706                 error "ofd_access_log_reader exited with rc = '${rc}'"
17707         fi
17708 }
17709 run_test 165d "ofd_access_log mask works"
17710
17711 test_165e() {
17712         local stats="/tmp/${tfile}.stats"
17713         local file0="${DIR}/${tdir}-0/${tfile}"
17714         local file1="${DIR}/${tdir}-1/${tfile}"
17715
17716         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17717                 skip "OFD access log unsupported"
17718
17719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17720
17721         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17722         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17723
17724         lfs setstripe -c 1 -i 0 "${file0}"
17725         lfs setstripe -c 1 -i 0 "${file1}"
17726
17727         setup_165
17728         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17729         sleep 5
17730
17731         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17732                 error "cannot create '${file0}'"
17733         sync
17734         oal_expect_read_count "${stats}" 0
17735
17736         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17737                 error "cannot create '${file1}'"
17738         sync
17739         oal_expect_read_count "${stats}" 1
17740
17741         do_facet ost1 killall -TERM ofd_access_log_reader
17742         wait
17743         rc=$?
17744         if ((rc != 0)); then
17745                 error "ofd_access_log_reader exited with rc = '${rc}'"
17746         fi
17747 }
17748 run_test 165e "ofd_access_log MDT index filter works"
17749
17750 test_165f() {
17751         local trace="/tmp/${tfile}.trace"
17752         local rc
17753         local count
17754
17755         setup_165
17756         do_facet ost1 timeout 60 ofd_access_log_reader \
17757                 --exit-on-close --debug=- --trace=- > "${trace}" &
17758         sleep 5
17759         stop ost1
17760
17761         wait
17762         rc=$?
17763
17764         if ((rc != 0)); then
17765                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17766                 cat "${trace}"
17767                 exit 1
17768         fi
17769 }
17770 run_test 165f "ofd_access_log_reader --exit-on-close works"
17771
17772 test_169() {
17773         # do directio so as not to populate the page cache
17774         log "creating a 10 Mb file"
17775         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17776                 error "multiop failed while creating a file"
17777         log "starting reads"
17778         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17779         log "truncating the file"
17780         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17781                 error "multiop failed while truncating the file"
17782         log "killing dd"
17783         kill %+ || true # reads might have finished
17784         echo "wait until dd is finished"
17785         wait
17786         log "removing the temporary file"
17787         rm -rf $DIR/$tfile || error "tmp file removal failed"
17788 }
17789 run_test 169 "parallel read and truncate should not deadlock"
17790
17791 test_170() {
17792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17793
17794         $LCTL clear     # bug 18514
17795         $LCTL debug_daemon start $TMP/${tfile}_log_good
17796         touch $DIR/$tfile
17797         $LCTL debug_daemon stop
17798         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17799                 error "sed failed to read log_good"
17800
17801         $LCTL debug_daemon start $TMP/${tfile}_log_good
17802         rm -rf $DIR/$tfile
17803         $LCTL debug_daemon stop
17804
17805         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17806                error "lctl df log_bad failed"
17807
17808         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17809         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17810
17811         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17812         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17813
17814         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17815                 error "bad_line good_line1 good_line2 are empty"
17816
17817         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17818         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17819         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17820
17821         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17822         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17823         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17824
17825         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17826                 error "bad_line_new good_line_new are empty"
17827
17828         local expected_good=$((good_line1 + good_line2*2))
17829
17830         rm -f $TMP/${tfile}*
17831         # LU-231, short malformed line may not be counted into bad lines
17832         if [ $bad_line -ne $bad_line_new ] &&
17833                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17834                 error "expected $bad_line bad lines, but got $bad_line_new"
17835                 return 1
17836         fi
17837
17838         if [ $expected_good -ne $good_line_new ]; then
17839                 error "expected $expected_good good lines, but got $good_line_new"
17840                 return 2
17841         fi
17842         true
17843 }
17844 run_test 170 "test lctl df to handle corrupted log ====================="
17845
17846 test_171() { # bug20592
17847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17848
17849         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17850         $LCTL set_param fail_loc=0x50e
17851         $LCTL set_param fail_val=3000
17852         multiop_bg_pause $DIR/$tfile O_s || true
17853         local MULTIPID=$!
17854         kill -USR1 $MULTIPID
17855         # cause log dump
17856         sleep 3
17857         wait $MULTIPID
17858         if dmesg | grep "recursive fault"; then
17859                 error "caught a recursive fault"
17860         fi
17861         $LCTL set_param fail_loc=0
17862         true
17863 }
17864 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17865
17866 test_172() {
17867
17868         #define OBD_FAIL_OBD_CLEANUP  0x60e
17869         $LCTL set_param fail_loc=0x60e
17870         umount $MOUNT || error "umount $MOUNT failed"
17871         stack_trap "mount_client $MOUNT"
17872
17873         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17874                 error "no client OBDs are remained"
17875
17876         $LCTL dl | while read devno state type name foo; do
17877                 case $type in
17878                 lov|osc|lmv|mdc)
17879                         $LCTL --device $name cleanup
17880                         $LCTL --device $name detach
17881                         ;;
17882                 *)
17883                         # skip server devices
17884                         ;;
17885                 esac
17886         done
17887
17888         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17889                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17890                 error "some client OBDs are still remained"
17891         fi
17892
17893 }
17894 run_test 172 "manual device removal with lctl cleanup/detach ======"
17895
17896 # it would be good to share it with obdfilter-survey/iokit-libecho code
17897 setup_obdecho_osc () {
17898         local rc=0
17899         local ost_nid=$1
17900         local obdfilter_name=$2
17901         echo "Creating new osc for $obdfilter_name on $ost_nid"
17902         # make sure we can find loopback nid
17903         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17904
17905         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17906                            ${obdfilter_name}_osc_UUID || rc=2; }
17907         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17908                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17909         return $rc
17910 }
17911
17912 cleanup_obdecho_osc () {
17913         local obdfilter_name=$1
17914         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17915         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17916         return 0
17917 }
17918
17919 obdecho_test() {
17920         local OBD=$1
17921         local node=$2
17922         local pages=${3:-64}
17923         local rc=0
17924         local id
17925
17926         local count=10
17927         local obd_size=$(get_obd_size $node $OBD)
17928         local page_size=$(get_page_size $node)
17929         if [[ -n "$obd_size" ]]; then
17930                 local new_count=$((obd_size / (pages * page_size / 1024)))
17931                 [[ $new_count -ge $count ]] || count=$new_count
17932         fi
17933
17934         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17935         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17936                            rc=2; }
17937         if [ $rc -eq 0 ]; then
17938             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17939             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17940         fi
17941         echo "New object id is $id"
17942         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17943                            rc=4; }
17944         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17945                            "test_brw $count w v $pages $id" || rc=4; }
17946         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17947                            rc=4; }
17948         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17949                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17950         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17951                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17952         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17953         return $rc
17954 }
17955
17956 test_180a() {
17957         skip "obdecho on osc is no longer supported"
17958 }
17959 run_test 180a "test obdecho on osc"
17960
17961 test_180b() {
17962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17963         remote_ost_nodsh && skip "remote OST with nodsh"
17964
17965         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17966                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17967                 error "failed to load module obdecho"
17968
17969         local target=$(do_facet ost1 $LCTL dl |
17970                        awk '/obdfilter/ { print $4; exit; }')
17971
17972         if [ -n "$target" ]; then
17973                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17974         else
17975                 do_facet ost1 $LCTL dl
17976                 error "there is no obdfilter target on ost1"
17977         fi
17978 }
17979 run_test 180b "test obdecho directly on obdfilter"
17980
17981 test_180c() { # LU-2598
17982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17983         remote_ost_nodsh && skip "remote OST with nodsh"
17984         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17985                 skip "Need MDS version at least 2.4.0"
17986
17987         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17988                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17989                 error "failed to load module obdecho"
17990
17991         local target=$(do_facet ost1 $LCTL dl |
17992                        awk '/obdfilter/ { print $4; exit; }')
17993
17994         if [ -n "$target" ]; then
17995                 local pages=16384 # 64MB bulk I/O RPC size
17996
17997                 obdecho_test "$target" ost1 "$pages" ||
17998                         error "obdecho_test with pages=$pages failed with $?"
17999         else
18000                 do_facet ost1 $LCTL dl
18001                 error "there is no obdfilter target on ost1"
18002         fi
18003 }
18004 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18005
18006 test_181() { # bug 22177
18007         test_mkdir $DIR/$tdir
18008         # create enough files to index the directory
18009         createmany -o $DIR/$tdir/foobar 4000
18010         # print attributes for debug purpose
18011         lsattr -d .
18012         # open dir
18013         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18014         MULTIPID=$!
18015         # remove the files & current working dir
18016         unlinkmany $DIR/$tdir/foobar 4000
18017         rmdir $DIR/$tdir
18018         kill -USR1 $MULTIPID
18019         wait $MULTIPID
18020         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18021         return 0
18022 }
18023 run_test 181 "Test open-unlinked dir ========================"
18024
18025 test_182a() {
18026         local fcount=1000
18027         local tcount=10
18028
18029         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18030
18031         $LCTL set_param mdc.*.rpc_stats=clear
18032
18033         for (( i = 0; i < $tcount; i++ )) ; do
18034                 mkdir $DIR/$tdir/$i
18035         done
18036
18037         for (( i = 0; i < $tcount; i++ )) ; do
18038                 createmany -o $DIR/$tdir/$i/f- $fcount &
18039         done
18040         wait
18041
18042         for (( i = 0; i < $tcount; i++ )) ; do
18043                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18044         done
18045         wait
18046
18047         $LCTL get_param mdc.*.rpc_stats
18048
18049         rm -rf $DIR/$tdir
18050 }
18051 run_test 182a "Test parallel modify metadata operations from mdc"
18052
18053 test_182b() {
18054         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18055         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18056         local dcount=1000
18057         local tcount=10
18058         local stime
18059         local etime
18060         local delta
18061
18062         do_facet mds1 $LCTL list_param \
18063                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18064                 skip "MDS lacks parallel RPC handling"
18065
18066         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18067
18068         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18069                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18070
18071         stime=$(date +%s)
18072         createmany -i 0 -d $DIR/$tdir/t- $tcount
18073
18074         for (( i = 0; i < $tcount; i++ )) ; do
18075                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18076         done
18077         wait
18078         etime=$(date +%s)
18079         delta=$((etime - stime))
18080         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18081
18082         stime=$(date +%s)
18083         for (( i = 0; i < $tcount; i++ )) ; do
18084                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18085         done
18086         wait
18087         etime=$(date +%s)
18088         delta=$((etime - stime))
18089         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18090
18091         rm -rf $DIR/$tdir
18092
18093         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18094
18095         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18096
18097         stime=$(date +%s)
18098         createmany -i 0 -d $DIR/$tdir/t- $tcount
18099
18100         for (( i = 0; i < $tcount; i++ )) ; do
18101                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18102         done
18103         wait
18104         etime=$(date +%s)
18105         delta=$((etime - stime))
18106         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18107
18108         stime=$(date +%s)
18109         for (( i = 0; i < $tcount; i++ )) ; do
18110                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18111         done
18112         wait
18113         etime=$(date +%s)
18114         delta=$((etime - stime))
18115         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18116
18117         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18118 }
18119 run_test 182b "Test parallel modify metadata operations from osp"
18120
18121 test_183() { # LU-2275
18122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18123         remote_mds_nodsh && skip "remote MDS with nodsh"
18124         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18125                 skip "Need MDS version at least 2.3.56"
18126
18127         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18128         echo aaa > $DIR/$tdir/$tfile
18129
18130 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18131         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18132
18133         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18134         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18135
18136         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18137
18138         # Flush negative dentry cache
18139         touch $DIR/$tdir/$tfile
18140
18141         # We are not checking for any leaked references here, they'll
18142         # become evident next time we do cleanup with module unload.
18143         rm -rf $DIR/$tdir
18144 }
18145 run_test 183 "No crash or request leak in case of strange dispositions ========"
18146
18147 # test suite 184 is for LU-2016, LU-2017
18148 test_184a() {
18149         check_swap_layouts_support
18150
18151         dir0=$DIR/$tdir/$testnum
18152         test_mkdir -p -c1 $dir0
18153         ref1=/etc/passwd
18154         ref2=/etc/group
18155         file1=$dir0/f1
18156         file2=$dir0/f2
18157         $LFS setstripe -c1 $file1
18158         cp $ref1 $file1
18159         $LFS setstripe -c2 $file2
18160         cp $ref2 $file2
18161         gen1=$($LFS getstripe -g $file1)
18162         gen2=$($LFS getstripe -g $file2)
18163
18164         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18165         gen=$($LFS getstripe -g $file1)
18166         [[ $gen1 != $gen ]] ||
18167                 error "Layout generation on $file1 does not change"
18168         gen=$($LFS getstripe -g $file2)
18169         [[ $gen2 != $gen ]] ||
18170                 error "Layout generation on $file2 does not change"
18171
18172         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18173         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18174
18175         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18176 }
18177 run_test 184a "Basic layout swap"
18178
18179 test_184b() {
18180         check_swap_layouts_support
18181
18182         dir0=$DIR/$tdir/$testnum
18183         mkdir -p $dir0 || error "creating dir $dir0"
18184         file1=$dir0/f1
18185         file2=$dir0/f2
18186         file3=$dir0/f3
18187         dir1=$dir0/d1
18188         dir2=$dir0/d2
18189         mkdir $dir1 $dir2
18190         $LFS setstripe -c1 $file1
18191         $LFS setstripe -c2 $file2
18192         $LFS setstripe -c1 $file3
18193         chown $RUNAS_ID $file3
18194         gen1=$($LFS getstripe -g $file1)
18195         gen2=$($LFS getstripe -g $file2)
18196
18197         $LFS swap_layouts $dir1 $dir2 &&
18198                 error "swap of directories layouts should fail"
18199         $LFS swap_layouts $dir1 $file1 &&
18200                 error "swap of directory and file layouts should fail"
18201         $RUNAS $LFS swap_layouts $file1 $file2 &&
18202                 error "swap of file we cannot write should fail"
18203         $LFS swap_layouts $file1 $file3 &&
18204                 error "swap of file with different owner should fail"
18205         /bin/true # to clear error code
18206 }
18207 run_test 184b "Forbidden layout swap (will generate errors)"
18208
18209 test_184c() {
18210         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18211         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18212         check_swap_layouts_support
18213         check_swap_layout_no_dom $DIR
18214
18215         local dir0=$DIR/$tdir/$testnum
18216         mkdir -p $dir0 || error "creating dir $dir0"
18217
18218         local ref1=$dir0/ref1
18219         local ref2=$dir0/ref2
18220         local file1=$dir0/file1
18221         local file2=$dir0/file2
18222         # create a file large enough for the concurrent test
18223         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18224         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18225         echo "ref file size: ref1($(stat -c %s $ref1))," \
18226              "ref2($(stat -c %s $ref2))"
18227
18228         cp $ref2 $file2
18229         dd if=$ref1 of=$file1 bs=16k &
18230         local DD_PID=$!
18231
18232         # Make sure dd starts to copy file, but wait at most 5 seconds
18233         local loops=0
18234         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18235
18236         $LFS swap_layouts $file1 $file2
18237         local rc=$?
18238         wait $DD_PID
18239         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18240         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18241
18242         # how many bytes copied before swapping layout
18243         local copied=$(stat -c %s $file2)
18244         local remaining=$(stat -c %s $ref1)
18245         remaining=$((remaining - copied))
18246         echo "Copied $copied bytes before swapping layout..."
18247
18248         cmp -n $copied $file1 $ref2 | grep differ &&
18249                 error "Content mismatch [0, $copied) of ref2 and file1"
18250         cmp -n $copied $file2 $ref1 ||
18251                 error "Content mismatch [0, $copied) of ref1 and file2"
18252         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18253                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18254
18255         # clean up
18256         rm -f $ref1 $ref2 $file1 $file2
18257 }
18258 run_test 184c "Concurrent write and layout swap"
18259
18260 test_184d() {
18261         check_swap_layouts_support
18262         check_swap_layout_no_dom $DIR
18263         [ -z "$(which getfattr 2>/dev/null)" ] &&
18264                 skip_env "no getfattr command"
18265
18266         local file1=$DIR/$tdir/$tfile-1
18267         local file2=$DIR/$tdir/$tfile-2
18268         local file3=$DIR/$tdir/$tfile-3
18269         local lovea1
18270         local lovea2
18271
18272         mkdir -p $DIR/$tdir
18273         touch $file1 || error "create $file1 failed"
18274         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18275                 error "create $file2 failed"
18276         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18277                 error "create $file3 failed"
18278         lovea1=$(get_layout_param $file1)
18279
18280         $LFS swap_layouts $file2 $file3 ||
18281                 error "swap $file2 $file3 layouts failed"
18282         $LFS swap_layouts $file1 $file2 ||
18283                 error "swap $file1 $file2 layouts failed"
18284
18285         lovea2=$(get_layout_param $file2)
18286         echo "$lovea1"
18287         echo "$lovea2"
18288         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18289
18290         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18291         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18292 }
18293 run_test 184d "allow stripeless layouts swap"
18294
18295 test_184e() {
18296         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18297                 skip "Need MDS version at least 2.6.94"
18298         check_swap_layouts_support
18299         check_swap_layout_no_dom $DIR
18300         [ -z "$(which getfattr 2>/dev/null)" ] &&
18301                 skip_env "no getfattr command"
18302
18303         local file1=$DIR/$tdir/$tfile-1
18304         local file2=$DIR/$tdir/$tfile-2
18305         local file3=$DIR/$tdir/$tfile-3
18306         local lovea
18307
18308         mkdir -p $DIR/$tdir
18309         touch $file1 || error "create $file1 failed"
18310         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18311                 error "create $file2 failed"
18312         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18313                 error "create $file3 failed"
18314
18315         $LFS swap_layouts $file1 $file2 ||
18316                 error "swap $file1 $file2 layouts failed"
18317
18318         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18319         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18320
18321         echo 123 > $file1 || error "Should be able to write into $file1"
18322
18323         $LFS swap_layouts $file1 $file3 ||
18324                 error "swap $file1 $file3 layouts failed"
18325
18326         echo 123 > $file1 || error "Should be able to write into $file1"
18327
18328         rm -rf $file1 $file2 $file3
18329 }
18330 run_test 184e "Recreate layout after stripeless layout swaps"
18331
18332 test_184f() {
18333         # Create a file with name longer than sizeof(struct stat) ==
18334         # 144 to see if we can get chars from the file name to appear
18335         # in the returned striping. Note that 'f' == 0x66.
18336         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18337
18338         mkdir -p $DIR/$tdir
18339         mcreate $DIR/$tdir/$file
18340         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18341                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18342         fi
18343 }
18344 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18345
18346 test_185() { # LU-2441
18347         # LU-3553 - no volatile file support in old servers
18348         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18349                 skip "Need MDS version at least 2.3.60"
18350
18351         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18352         touch $DIR/$tdir/spoo
18353         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18354         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18355                 error "cannot create/write a volatile file"
18356         [ "$FILESET" == "" ] &&
18357         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18358                 error "FID is still valid after close"
18359
18360         multiop_bg_pause $DIR/$tdir vVw4096_c
18361         local multi_pid=$!
18362
18363         local OLD_IFS=$IFS
18364         IFS=":"
18365         local fidv=($fid)
18366         IFS=$OLD_IFS
18367         # assume that the next FID for this client is sequential, since stdout
18368         # is unfortunately eaten by multiop_bg_pause
18369         local n=$((${fidv[1]} + 1))
18370         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18371         if [ "$FILESET" == "" ]; then
18372                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18373                         error "FID is missing before close"
18374         fi
18375         kill -USR1 $multi_pid
18376         # 1 second delay, so if mtime change we will see it
18377         sleep 1
18378         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18379         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18380 }
18381 run_test 185 "Volatile file support"
18382
18383 function create_check_volatile() {
18384         local idx=$1
18385         local tgt
18386
18387         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18388         local PID=$!
18389         sleep 1
18390         local FID=$(cat /tmp/${tfile}.fid)
18391         [ "$FID" == "" ] && error "can't get FID for volatile"
18392         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18393         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18394         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18395         kill -USR1 $PID
18396         wait
18397         sleep 1
18398         cancel_lru_locks mdc # flush opencache
18399         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18400         return 0
18401 }
18402
18403 test_185a(){
18404         # LU-12516 - volatile creation via .lustre
18405         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18406                 skip "Need MDS version at least 2.3.55"
18407
18408         create_check_volatile 0
18409         [ $MDSCOUNT -lt 2 ] && return 0
18410
18411         # DNE case
18412         create_check_volatile 1
18413
18414         return 0
18415 }
18416 run_test 185a "Volatile file creation in .lustre/fid/"
18417
18418 test_187a() {
18419         remote_mds_nodsh && skip "remote MDS with nodsh"
18420         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18421                 skip "Need MDS version at least 2.3.0"
18422
18423         local dir0=$DIR/$tdir/$testnum
18424         mkdir -p $dir0 || error "creating dir $dir0"
18425
18426         local file=$dir0/file1
18427         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18428         local dv1=$($LFS data_version $file)
18429         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18430         local dv2=$($LFS data_version $file)
18431         [[ $dv1 != $dv2 ]] ||
18432                 error "data version did not change on write $dv1 == $dv2"
18433
18434         # clean up
18435         rm -f $file1
18436 }
18437 run_test 187a "Test data version change"
18438
18439 test_187b() {
18440         remote_mds_nodsh && skip "remote MDS with nodsh"
18441         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18442                 skip "Need MDS version at least 2.3.0"
18443
18444         local dir0=$DIR/$tdir/$testnum
18445         mkdir -p $dir0 || error "creating dir $dir0"
18446
18447         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18448         [[ ${DV[0]} != ${DV[1]} ]] ||
18449                 error "data version did not change on write"\
18450                       " ${DV[0]} == ${DV[1]}"
18451
18452         # clean up
18453         rm -f $file1
18454 }
18455 run_test 187b "Test data version change on volatile file"
18456
18457 test_200() {
18458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18459         remote_mgs_nodsh && skip "remote MGS with nodsh"
18460         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18461
18462         local POOL=${POOL:-cea1}
18463         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18464         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18465         # Pool OST targets
18466         local first_ost=0
18467         local last_ost=$(($OSTCOUNT - 1))
18468         local ost_step=2
18469         local ost_list=$(seq $first_ost $ost_step $last_ost)
18470         local ost_range="$first_ost $last_ost $ost_step"
18471         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18472         local file_dir=$POOL_ROOT/file_tst
18473         local subdir=$test_path/subdir
18474         local rc=0
18475
18476         while : ; do
18477                 # former test_200a test_200b
18478                 pool_add $POOL                          || { rc=$? ; break; }
18479                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18480                 # former test_200c test_200d
18481                 mkdir -p $test_path
18482                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18483                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18484                 mkdir -p $subdir
18485                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18486                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18487                                                         || { rc=$? ; break; }
18488                 # former test_200e test_200f
18489                 local files=$((OSTCOUNT*3))
18490                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18491                                                         || { rc=$? ; break; }
18492                 pool_create_files $POOL $file_dir $files "$ost_list" \
18493                                                         || { rc=$? ; break; }
18494                 # former test_200g test_200h
18495                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18496                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18497
18498                 # former test_201a test_201b test_201c
18499                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18500
18501                 local f=$test_path/$tfile
18502                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18503                 pool_remove $POOL $f                    || { rc=$? ; break; }
18504                 break
18505         done
18506
18507         destroy_test_pools
18508
18509         return $rc
18510 }
18511 run_test 200 "OST pools"
18512
18513 # usage: default_attr <count | size | offset>
18514 default_attr() {
18515         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18516 }
18517
18518 # usage: check_default_stripe_attr
18519 check_default_stripe_attr() {
18520         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18521         case $1 in
18522         --stripe-count|-c)
18523                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18524         --stripe-size|-S)
18525                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18526         --stripe-index|-i)
18527                 EXPECTED=-1;;
18528         *)
18529                 error "unknown getstripe attr '$1'"
18530         esac
18531
18532         [ $ACTUAL == $EXPECTED ] ||
18533                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18534 }
18535
18536 test_204a() {
18537         test_mkdir $DIR/$tdir
18538         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18539
18540         check_default_stripe_attr --stripe-count
18541         check_default_stripe_attr --stripe-size
18542         check_default_stripe_attr --stripe-index
18543 }
18544 run_test 204a "Print default stripe attributes"
18545
18546 test_204b() {
18547         test_mkdir $DIR/$tdir
18548         $LFS setstripe --stripe-count 1 $DIR/$tdir
18549
18550         check_default_stripe_attr --stripe-size
18551         check_default_stripe_attr --stripe-index
18552 }
18553 run_test 204b "Print default stripe size and offset"
18554
18555 test_204c() {
18556         test_mkdir $DIR/$tdir
18557         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18558
18559         check_default_stripe_attr --stripe-count
18560         check_default_stripe_attr --stripe-index
18561 }
18562 run_test 204c "Print default stripe count and offset"
18563
18564 test_204d() {
18565         test_mkdir $DIR/$tdir
18566         $LFS setstripe --stripe-index 0 $DIR/$tdir
18567
18568         check_default_stripe_attr --stripe-count
18569         check_default_stripe_attr --stripe-size
18570 }
18571 run_test 204d "Print default stripe count and size"
18572
18573 test_204e() {
18574         test_mkdir $DIR/$tdir
18575         $LFS setstripe -d $DIR/$tdir
18576
18577         check_default_stripe_attr --stripe-count --raw
18578         check_default_stripe_attr --stripe-size --raw
18579         check_default_stripe_attr --stripe-index --raw
18580 }
18581 run_test 204e "Print raw stripe attributes"
18582
18583 test_204f() {
18584         test_mkdir $DIR/$tdir
18585         $LFS setstripe --stripe-count 1 $DIR/$tdir
18586
18587         check_default_stripe_attr --stripe-size --raw
18588         check_default_stripe_attr --stripe-index --raw
18589 }
18590 run_test 204f "Print raw stripe size and offset"
18591
18592 test_204g() {
18593         test_mkdir $DIR/$tdir
18594         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18595
18596         check_default_stripe_attr --stripe-count --raw
18597         check_default_stripe_attr --stripe-index --raw
18598 }
18599 run_test 204g "Print raw stripe count and offset"
18600
18601 test_204h() {
18602         test_mkdir $DIR/$tdir
18603         $LFS setstripe --stripe-index 0 $DIR/$tdir
18604
18605         check_default_stripe_attr --stripe-count --raw
18606         check_default_stripe_attr --stripe-size --raw
18607 }
18608 run_test 204h "Print raw stripe count and size"
18609
18610 # Figure out which job scheduler is being used, if any,
18611 # or use a fake one
18612 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18613         JOBENV=SLURM_JOB_ID
18614 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18615         JOBENV=LSB_JOBID
18616 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18617         JOBENV=PBS_JOBID
18618 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18619         JOBENV=LOADL_STEP_ID
18620 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18621         JOBENV=JOB_ID
18622 else
18623         $LCTL list_param jobid_name > /dev/null 2>&1
18624         if [ $? -eq 0 ]; then
18625                 JOBENV=nodelocal
18626         else
18627                 JOBENV=FAKE_JOBID
18628         fi
18629 fi
18630 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18631
18632 verify_jobstats() {
18633         local cmd=($1)
18634         shift
18635         local facets="$@"
18636
18637 # we don't really need to clear the stats for this test to work, since each
18638 # command has a unique jobid, but it makes debugging easier if needed.
18639 #       for facet in $facets; do
18640 #               local dev=$(convert_facet2label $facet)
18641 #               # clear old jobstats
18642 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18643 #       done
18644
18645         # use a new JobID for each test, or we might see an old one
18646         [ "$JOBENV" = "FAKE_JOBID" ] &&
18647                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18648
18649         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18650
18651         [ "$JOBENV" = "nodelocal" ] && {
18652                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18653                 $LCTL set_param jobid_name=$FAKE_JOBID
18654                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18655         }
18656
18657         log "Test: ${cmd[*]}"
18658         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18659
18660         if [ $JOBENV = "FAKE_JOBID" ]; then
18661                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18662         else
18663                 ${cmd[*]}
18664         fi
18665
18666         # all files are created on OST0000
18667         for facet in $facets; do
18668                 local stats="*.$(convert_facet2label $facet).job_stats"
18669
18670                 # strip out libtool wrappers for in-tree executables
18671                 if (( $(do_facet $facet lctl get_param $stats |
18672                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18673                         do_facet $facet lctl get_param $stats
18674                         error "No jobstats for $JOBVAL found on $facet::$stats"
18675                 fi
18676         done
18677 }
18678
18679 jobstats_set() {
18680         local new_jobenv=$1
18681
18682         set_persistent_param_and_check client "jobid_var" \
18683                 "$FSNAME.sys.jobid_var" $new_jobenv
18684 }
18685
18686 test_205a() { # Job stats
18687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18688         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18689                 skip "Need MDS version with at least 2.7.1"
18690         remote_mgs_nodsh && skip "remote MGS with nodsh"
18691         remote_mds_nodsh && skip "remote MDS with nodsh"
18692         remote_ost_nodsh && skip "remote OST with nodsh"
18693         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18694                 skip "Server doesn't support jobstats"
18695         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18696
18697         local old_jobenv=$($LCTL get_param -n jobid_var)
18698         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18699
18700         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18701                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18702         else
18703                 stack_trap "do_facet mgs $PERM_CMD \
18704                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18705         fi
18706         changelog_register
18707
18708         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18709                                 mdt.*.job_cleanup_interval | head -n 1)
18710         local new_interval=5
18711         do_facet $SINGLEMDS \
18712                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18713         stack_trap "do_facet $SINGLEMDS \
18714                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18715         local start=$SECONDS
18716
18717         local cmd
18718         # mkdir
18719         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18720         verify_jobstats "$cmd" "$SINGLEMDS"
18721         # rmdir
18722         cmd="rmdir $DIR/$tdir"
18723         verify_jobstats "$cmd" "$SINGLEMDS"
18724         # mkdir on secondary MDT
18725         if [ $MDSCOUNT -gt 1 ]; then
18726                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18727                 verify_jobstats "$cmd" "mds2"
18728         fi
18729         # mknod
18730         cmd="mknod $DIR/$tfile c 1 3"
18731         verify_jobstats "$cmd" "$SINGLEMDS"
18732         # unlink
18733         cmd="rm -f $DIR/$tfile"
18734         verify_jobstats "$cmd" "$SINGLEMDS"
18735         # create all files on OST0000 so verify_jobstats can find OST stats
18736         # open & close
18737         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18738         verify_jobstats "$cmd" "$SINGLEMDS"
18739         # setattr
18740         cmd="touch $DIR/$tfile"
18741         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18742         # write
18743         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18744         verify_jobstats "$cmd" "ost1"
18745         # read
18746         cancel_lru_locks osc
18747         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18748         verify_jobstats "$cmd" "ost1"
18749         # truncate
18750         cmd="$TRUNCATE $DIR/$tfile 0"
18751         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18752         # rename
18753         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18754         verify_jobstats "$cmd" "$SINGLEMDS"
18755         # jobstats expiry - sleep until old stats should be expired
18756         local left=$((new_interval + 5 - (SECONDS - start)))
18757         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18758                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18759                         "0" $left
18760         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18761         verify_jobstats "$cmd" "$SINGLEMDS"
18762         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18763             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18764
18765         # Ensure that jobid are present in changelog (if supported by MDS)
18766         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18767                 changelog_dump | tail -10
18768                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18769                 [ $jobids -eq 9 ] ||
18770                         error "Wrong changelog jobid count $jobids != 9"
18771
18772                 # LU-5862
18773                 JOBENV="disable"
18774                 jobstats_set $JOBENV
18775                 touch $DIR/$tfile
18776                 changelog_dump | grep $tfile
18777                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18778                 [ $jobids -eq 0 ] ||
18779                         error "Unexpected jobids when jobid_var=$JOBENV"
18780         fi
18781
18782         # test '%j' access to environment variable - if supported
18783         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18784                 JOBENV="JOBCOMPLEX"
18785                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18786
18787                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18788         fi
18789
18790         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18791                 JOBENV="JOBCOMPLEX"
18792                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18793
18794                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18795         fi
18796
18797         # test '%j' access to per-session jobid - if supported
18798         if lctl list_param jobid_this_session > /dev/null 2>&1
18799         then
18800                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18801                 lctl set_param jobid_this_session=$USER
18802
18803                 JOBENV="JOBCOMPLEX"
18804                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18805
18806                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18807         fi
18808 }
18809 run_test 205a "Verify job stats"
18810
18811 # LU-13117, LU-13597
18812 test_205b() {
18813         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18814                 skip "Need MDS version at least 2.13.54.91"
18815
18816         local job_stats="mdt.*.job_stats"
18817         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18818
18819         do_facet mds1 $LCTL set_param $job_stats=clear
18820
18821         # Setting jobid_var to USER might not be supported
18822         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18823         $LCTL set_param jobid_var=USER || true
18824         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18825         $LCTL set_param jobid_name="%j.%e.%u"
18826
18827         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18828         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18829                 { do_facet mds1 $LCTL get_param $job_stats;
18830                   error "Unexpected jobid found"; }
18831         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18832                 { do_facet mds1 $LCTL get_param $job_stats;
18833                   error "wrong job_stats format found"; }
18834
18835         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18836                 echo "MDS does not yet escape jobid" && return 0
18837         $LCTL set_param jobid_var=TEST205b
18838         env -i TEST205b="has sp" touch $DIR/$tfile.2
18839         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18840                 { do_facet mds1 $LCTL get_param $job_stats;
18841                   error "jobid not escaped"; }
18842 }
18843 run_test 205b "Verify job stats jobid and output format"
18844
18845 # LU-13733
18846 test_205c() {
18847         $LCTL set_param llite.*.stats=0
18848         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18849         $LCTL get_param llite.*.stats
18850         $LCTL get_param llite.*.stats | grep \
18851                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18852                         error "wrong client stats format found"
18853 }
18854 run_test 205c "Verify client stats format"
18855
18856 # LU-1480, LU-1773 and LU-1657
18857 test_206() {
18858         mkdir -p $DIR/$tdir
18859         $LFS setstripe -c -1 $DIR/$tdir
18860 #define OBD_FAIL_LOV_INIT 0x1403
18861         $LCTL set_param fail_loc=0xa0001403
18862         $LCTL set_param fail_val=1
18863         touch $DIR/$tdir/$tfile || true
18864 }
18865 run_test 206 "fail lov_init_raid0() doesn't lbug"
18866
18867 test_207a() {
18868         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18869         local fsz=`stat -c %s $DIR/$tfile`
18870         cancel_lru_locks mdc
18871
18872         # do not return layout in getattr intent
18873 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18874         $LCTL set_param fail_loc=0x170
18875         local sz=`stat -c %s $DIR/$tfile`
18876
18877         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18878
18879         rm -rf $DIR/$tfile
18880 }
18881 run_test 207a "can refresh layout at glimpse"
18882
18883 test_207b() {
18884         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18885         local cksum=`md5sum $DIR/$tfile`
18886         local fsz=`stat -c %s $DIR/$tfile`
18887         cancel_lru_locks mdc
18888         cancel_lru_locks osc
18889
18890         # do not return layout in getattr intent
18891 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18892         $LCTL set_param fail_loc=0x171
18893
18894         # it will refresh layout after the file is opened but before read issues
18895         echo checksum is "$cksum"
18896         echo "$cksum" |md5sum -c --quiet || error "file differs"
18897
18898         rm -rf $DIR/$tfile
18899 }
18900 run_test 207b "can refresh layout at open"
18901
18902 test_208() {
18903         # FIXME: in this test suite, only RD lease is used. This is okay
18904         # for now as only exclusive open is supported. After generic lease
18905         # is done, this test suite should be revised. - Jinshan
18906
18907         remote_mds_nodsh && skip "remote MDS with nodsh"
18908         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18909                 skip "Need MDS version at least 2.4.52"
18910
18911         echo "==== test 1: verify get lease work"
18912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18913
18914         echo "==== test 2: verify lease can be broken by upcoming open"
18915         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18916         local PID=$!
18917         sleep 2
18918
18919         $MULTIOP $DIR/$tfile oO_RDWR:c
18920         kill -USR1 $PID && wait $PID || error "break lease error"
18921
18922         echo "==== test 3: verify lease can't be granted if an open already exists"
18923         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18924         local PID=$!
18925         sleep 2
18926
18927         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18928         kill -USR1 $PID && wait $PID || error "open file error"
18929
18930         echo "==== test 4: lease can sustain over recovery"
18931         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18932         PID=$!
18933         sleep 2
18934
18935         fail mds1
18936
18937         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18938
18939         echo "==== test 5: lease broken can't be regained by replay"
18940         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18941         PID=$!
18942         sleep 2
18943
18944         # open file to break lease and then recovery
18945         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18946         fail mds1
18947
18948         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18949
18950         rm -f $DIR/$tfile
18951 }
18952 run_test 208 "Exclusive open"
18953
18954 test_209() {
18955         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18956                 skip_env "must have disp_stripe"
18957
18958         touch $DIR/$tfile
18959         sync; sleep 5; sync;
18960
18961         echo 3 > /proc/sys/vm/drop_caches
18962         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18963                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18964         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18965
18966         # open/close 500 times
18967         for i in $(seq 500); do
18968                 cat $DIR/$tfile
18969         done
18970
18971         echo 3 > /proc/sys/vm/drop_caches
18972         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18973                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18974         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18975
18976         echo "before: $req_before, after: $req_after"
18977         [ $((req_after - req_before)) -ge 300 ] &&
18978                 error "open/close requests are not freed"
18979         return 0
18980 }
18981 run_test 209 "read-only open/close requests should be freed promptly"
18982
18983 test_210() {
18984         local pid
18985
18986         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18987         pid=$!
18988         sleep 1
18989
18990         $LFS getstripe $DIR/$tfile
18991         kill -USR1 $pid
18992         wait $pid || error "multiop failed"
18993
18994         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18995         pid=$!
18996         sleep 1
18997
18998         $LFS getstripe $DIR/$tfile
18999         kill -USR1 $pid
19000         wait $pid || error "multiop failed"
19001 }
19002 run_test 210 "lfs getstripe does not break leases"
19003
19004 test_212() {
19005         size=`date +%s`
19006         size=$((size % 8192 + 1))
19007         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19008         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19009         rm -f $DIR/f212 $DIR/f212.xyz
19010 }
19011 run_test 212 "Sendfile test ============================================"
19012
19013 test_213() {
19014         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19015         cancel_lru_locks osc
19016         lctl set_param fail_loc=0x8000040f
19017         # generate a read lock
19018         cat $DIR/$tfile > /dev/null
19019         # write to the file, it will try to cancel the above read lock.
19020         cat /etc/hosts >> $DIR/$tfile
19021 }
19022 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19023
19024 test_214() { # for bug 20133
19025         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19026         for (( i=0; i < 340; i++ )) ; do
19027                 touch $DIR/$tdir/d214c/a$i
19028         done
19029
19030         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19031         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19032         ls $DIR/d214c || error "ls $DIR/d214c failed"
19033         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19034         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19035 }
19036 run_test 214 "hash-indexed directory test - bug 20133"
19037
19038 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19039 create_lnet_proc_files() {
19040         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19041 }
19042
19043 # counterpart of create_lnet_proc_files
19044 remove_lnet_proc_files() {
19045         rm -f $TMP/lnet_$1.sys
19046 }
19047
19048 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19049 # 3rd arg as regexp for body
19050 check_lnet_proc_stats() {
19051         local l=$(cat "$TMP/lnet_$1" |wc -l)
19052         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19053
19054         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19055 }
19056
19057 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19058 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19059 # optional and can be regexp for 2nd line (lnet.routes case)
19060 check_lnet_proc_entry() {
19061         local blp=2          # blp stands for 'position of 1st line of body'
19062         [ -z "$5" ] || blp=3 # lnet.routes case
19063
19064         local l=$(cat "$TMP/lnet_$1" |wc -l)
19065         # subtracting one from $blp because the body can be empty
19066         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19067
19068         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19069                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19070
19071         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19072                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19073
19074         # bail out if any unexpected line happened
19075         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19076         [ "$?" != 0 ] || error "$2 misformatted"
19077 }
19078
19079 test_215() { # for bugs 18102, 21079, 21517
19080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19081
19082         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19083         local P='[1-9][0-9]*'           # positive numeric
19084         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19085         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19086         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19087         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19088
19089         local L1 # regexp for 1st line
19090         local L2 # regexp for 2nd line (optional)
19091         local BR # regexp for the rest (body)
19092
19093         # lnet.stats should look as 11 space-separated non-negative numerics
19094         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19095         create_lnet_proc_files "stats"
19096         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19097         remove_lnet_proc_files "stats"
19098
19099         # lnet.routes should look like this:
19100         # Routing disabled/enabled
19101         # net hops priority state router
19102         # where net is a string like tcp0, hops > 0, priority >= 0,
19103         # state is up/down,
19104         # router is a string like 192.168.1.1@tcp2
19105         L1="^Routing (disabled|enabled)$"
19106         L2="^net +hops +priority +state +router$"
19107         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19108         create_lnet_proc_files "routes"
19109         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19110         remove_lnet_proc_files "routes"
19111
19112         # lnet.routers should look like this:
19113         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19114         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19115         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19116         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19117         L1="^ref +rtr_ref +alive +router$"
19118         BR="^$P +$P +(up|down) +$NID$"
19119         create_lnet_proc_files "routers"
19120         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19121         remove_lnet_proc_files "routers"
19122
19123         # lnet.peers should look like this:
19124         # nid refs state last max rtr min tx min queue
19125         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19126         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19127         # numeric (0 or >0 or <0), queue >= 0.
19128         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19129         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19130         create_lnet_proc_files "peers"
19131         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19132         remove_lnet_proc_files "peers"
19133
19134         # lnet.buffers  should look like this:
19135         # pages count credits min
19136         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19137         L1="^pages +count +credits +min$"
19138         BR="^ +$N +$N +$I +$I$"
19139         create_lnet_proc_files "buffers"
19140         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19141         remove_lnet_proc_files "buffers"
19142
19143         # lnet.nis should look like this:
19144         # nid status alive refs peer rtr max tx min
19145         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19146         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19147         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19148         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19149         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19150         create_lnet_proc_files "nis"
19151         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19152         remove_lnet_proc_files "nis"
19153
19154         # can we successfully write to lnet.stats?
19155         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19156 }
19157 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19158
19159 test_216() { # bug 20317
19160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19161         remote_ost_nodsh && skip "remote OST with nodsh"
19162
19163         local node
19164         local facets=$(get_facets OST)
19165         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19166
19167         save_lustre_params client "osc.*.contention_seconds" > $p
19168         save_lustre_params $facets \
19169                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19170         save_lustre_params $facets \
19171                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19172         save_lustre_params $facets \
19173                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19174         clear_stats osc.*.osc_stats
19175
19176         # agressive lockless i/o settings
19177         do_nodes $(comma_list $(osts_nodes)) \
19178                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19179                         ldlm.namespaces.filter-*.contended_locks=0 \
19180                         ldlm.namespaces.filter-*.contention_seconds=60"
19181         lctl set_param -n osc.*.contention_seconds=60
19182
19183         $DIRECTIO write $DIR/$tfile 0 10 4096
19184         $CHECKSTAT -s 40960 $DIR/$tfile
19185
19186         # disable lockless i/o
19187         do_nodes $(comma_list $(osts_nodes)) \
19188                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19189                         ldlm.namespaces.filter-*.contended_locks=32 \
19190                         ldlm.namespaces.filter-*.contention_seconds=0"
19191         lctl set_param -n osc.*.contention_seconds=0
19192         clear_stats osc.*.osc_stats
19193
19194         dd if=/dev/zero of=$DIR/$tfile count=0
19195         $CHECKSTAT -s 0 $DIR/$tfile
19196
19197         restore_lustre_params <$p
19198         rm -f $p
19199         rm $DIR/$tfile
19200 }
19201 run_test 216 "check lockless direct write updates file size and kms correctly"
19202
19203 test_217() { # bug 22430
19204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19205
19206         local node
19207         local nid
19208
19209         for node in $(nodes_list); do
19210                 nid=$(host_nids_address $node $NETTYPE)
19211                 if [[ $nid = *-* ]] ; then
19212                         echo "lctl ping $(h2nettype $nid)"
19213                         lctl ping $(h2nettype $nid)
19214                 else
19215                         echo "skipping $node (no hyphen detected)"
19216                 fi
19217         done
19218 }
19219 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19220
19221 test_218() {
19222        # do directio so as not to populate the page cache
19223        log "creating a 10 Mb file"
19224        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19225        log "starting reads"
19226        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19227        log "truncating the file"
19228        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19229        log "killing dd"
19230        kill %+ || true # reads might have finished
19231        echo "wait until dd is finished"
19232        wait
19233        log "removing the temporary file"
19234        rm -rf $DIR/$tfile || error "tmp file removal failed"
19235 }
19236 run_test 218 "parallel read and truncate should not deadlock"
19237
19238 test_219() {
19239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19240
19241         # write one partial page
19242         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19243         # set no grant so vvp_io_commit_write will do sync write
19244         $LCTL set_param fail_loc=0x411
19245         # write a full page at the end of file
19246         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19247
19248         $LCTL set_param fail_loc=0
19249         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19250         $LCTL set_param fail_loc=0x411
19251         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19252
19253         # LU-4201
19254         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19255         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19256 }
19257 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19258
19259 test_220() { #LU-325
19260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19261         remote_ost_nodsh && skip "remote OST with nodsh"
19262         remote_mds_nodsh && skip "remote MDS with nodsh"
19263         remote_mgs_nodsh && skip "remote MGS with nodsh"
19264
19265         local OSTIDX=0
19266
19267         # create on MDT0000 so the last_id and next_id are correct
19268         mkdir_on_mdt0 $DIR/$tdir
19269         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19270         OST=${OST%_UUID}
19271
19272         # on the mdt's osc
19273         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19274         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19275                         osp.$mdtosc_proc1.prealloc_last_id)
19276         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19277                         osp.$mdtosc_proc1.prealloc_next_id)
19278
19279         $LFS df -i
19280
19281         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19282         #define OBD_FAIL_OST_ENOINO              0x229
19283         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19284         create_pool $FSNAME.$TESTNAME || return 1
19285         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19286
19287         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19288
19289         MDSOBJS=$((last_id - next_id))
19290         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19291
19292         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19293         echo "OST still has $count kbytes free"
19294
19295         echo "create $MDSOBJS files @next_id..."
19296         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19297
19298         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19299                         osp.$mdtosc_proc1.prealloc_last_id)
19300         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19301                         osp.$mdtosc_proc1.prealloc_next_id)
19302
19303         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19304         $LFS df -i
19305
19306         echo "cleanup..."
19307
19308         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19309         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19310
19311         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19312                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19313         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19314                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19315         echo "unlink $MDSOBJS files @$next_id..."
19316         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19317 }
19318 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19319
19320 test_221() {
19321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19322
19323         dd if=`which date` of=$MOUNT/date oflag=sync
19324         chmod +x $MOUNT/date
19325
19326         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19327         $LCTL set_param fail_loc=0x80001401
19328
19329         $MOUNT/date > /dev/null
19330         rm -f $MOUNT/date
19331 }
19332 run_test 221 "make sure fault and truncate race to not cause OOM"
19333
19334 test_222a () {
19335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19336
19337         rm -rf $DIR/$tdir
19338         test_mkdir $DIR/$tdir
19339         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19340         createmany -o $DIR/$tdir/$tfile 10
19341         cancel_lru_locks mdc
19342         cancel_lru_locks osc
19343         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19344         $LCTL set_param fail_loc=0x31a
19345         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19346         $LCTL set_param fail_loc=0
19347         rm -r $DIR/$tdir
19348 }
19349 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19350
19351 test_222b () {
19352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19353
19354         rm -rf $DIR/$tdir
19355         test_mkdir $DIR/$tdir
19356         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19357         createmany -o $DIR/$tdir/$tfile 10
19358         cancel_lru_locks mdc
19359         cancel_lru_locks osc
19360         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19361         $LCTL set_param fail_loc=0x31a
19362         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19363         $LCTL set_param fail_loc=0
19364 }
19365 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19366
19367 test_223 () {
19368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19369
19370         rm -rf $DIR/$tdir
19371         test_mkdir $DIR/$tdir
19372         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19373         createmany -o $DIR/$tdir/$tfile 10
19374         cancel_lru_locks mdc
19375         cancel_lru_locks osc
19376         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19377         $LCTL set_param fail_loc=0x31b
19378         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19379         $LCTL set_param fail_loc=0
19380         rm -r $DIR/$tdir
19381 }
19382 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19383
19384 test_224a() { # LU-1039, MRP-303
19385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19386         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19387         $LCTL set_param fail_loc=0x508
19388         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19389         $LCTL set_param fail_loc=0
19390         df $DIR
19391 }
19392 run_test 224a "Don't panic on bulk IO failure"
19393
19394 test_224bd_sub() { # LU-1039, MRP-303
19395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19396         local timeout=$1
19397
19398         shift
19399         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19400
19401         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19402
19403         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19404         cancel_lru_locks osc
19405         set_checksums 0
19406         stack_trap "set_checksums $ORIG_CSUM" EXIT
19407         local at_max_saved=0
19408
19409         # adaptive timeouts may prevent seeing the issue
19410         if at_is_enabled; then
19411                 at_max_saved=$(at_max_get mds)
19412                 at_max_set 0 mds client
19413                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19414         fi
19415
19416         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19417         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19418         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19419
19420         do_facet ost1 $LCTL set_param fail_loc=0
19421         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19422         df $DIR
19423 }
19424
19425 test_224b() {
19426         test_224bd_sub 3 error "dd failed"
19427 }
19428 run_test 224b "Don't panic on bulk IO failure"
19429
19430 test_224c() { # LU-6441
19431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19432         remote_mds_nodsh && skip "remote MDS with nodsh"
19433
19434         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19435         save_writethrough $p
19436         set_cache writethrough on
19437
19438         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19439         local at_max=$($LCTL get_param -n at_max)
19440         local timeout=$($LCTL get_param -n timeout)
19441         local test_at="at_max"
19442         local param_at="$FSNAME.sys.at_max"
19443         local test_timeout="timeout"
19444         local param_timeout="$FSNAME.sys.timeout"
19445
19446         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19447
19448         set_persistent_param_and_check client "$test_at" "$param_at" 0
19449         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19450
19451         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19452         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19453         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19454         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19455         sync
19456         do_facet ost1 "$LCTL set_param fail_loc=0"
19457
19458         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19459         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19460                 $timeout
19461
19462         $LCTL set_param -n $pages_per_rpc
19463         restore_lustre_params < $p
19464         rm -f $p
19465 }
19466 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19467
19468 test_224d() { # LU-11169
19469         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19470 }
19471 run_test 224d "Don't corrupt data on bulk IO timeout"
19472
19473 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19474 test_225a () {
19475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19476         if [ -z ${MDSSURVEY} ]; then
19477                 skip_env "mds-survey not found"
19478         fi
19479         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19480                 skip "Need MDS version at least 2.2.51"
19481
19482         local mds=$(facet_host $SINGLEMDS)
19483         local target=$(do_nodes $mds 'lctl dl' |
19484                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19485
19486         local cmd1="file_count=1000 thrhi=4"
19487         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19488         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19489         local cmd="$cmd1 $cmd2 $cmd3"
19490
19491         rm -f ${TMP}/mds_survey*
19492         echo + $cmd
19493         eval $cmd || error "mds-survey with zero-stripe failed"
19494         cat ${TMP}/mds_survey*
19495         rm -f ${TMP}/mds_survey*
19496 }
19497 run_test 225a "Metadata survey sanity with zero-stripe"
19498
19499 test_225b () {
19500         if [ -z ${MDSSURVEY} ]; then
19501                 skip_env "mds-survey not found"
19502         fi
19503         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19504                 skip "Need MDS version at least 2.2.51"
19505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19506         remote_mds_nodsh && skip "remote MDS with nodsh"
19507         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19508                 skip_env "Need to mount OST to test"
19509         fi
19510
19511         local mds=$(facet_host $SINGLEMDS)
19512         local target=$(do_nodes $mds 'lctl dl' |
19513                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19514
19515         local cmd1="file_count=1000 thrhi=4"
19516         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19517         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19518         local cmd="$cmd1 $cmd2 $cmd3"
19519
19520         rm -f ${TMP}/mds_survey*
19521         echo + $cmd
19522         eval $cmd || error "mds-survey with stripe_count failed"
19523         cat ${TMP}/mds_survey*
19524         rm -f ${TMP}/mds_survey*
19525 }
19526 run_test 225b "Metadata survey sanity with stripe_count = 1"
19527
19528 mcreate_path2fid () {
19529         local mode=$1
19530         local major=$2
19531         local minor=$3
19532         local name=$4
19533         local desc=$5
19534         local path=$DIR/$tdir/$name
19535         local fid
19536         local rc
19537         local fid_path
19538
19539         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19540                 error "cannot create $desc"
19541
19542         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19543         rc=$?
19544         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19545
19546         fid_path=$($LFS fid2path $MOUNT $fid)
19547         rc=$?
19548         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19549
19550         [ "$path" == "$fid_path" ] ||
19551                 error "fid2path returned $fid_path, expected $path"
19552
19553         echo "pass with $path and $fid"
19554 }
19555
19556 test_226a () {
19557         rm -rf $DIR/$tdir
19558         mkdir -p $DIR/$tdir
19559
19560         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19561         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19562         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19563         mcreate_path2fid 0040666 0 0 dir "directory"
19564         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19565         mcreate_path2fid 0100666 0 0 file "regular file"
19566         mcreate_path2fid 0120666 0 0 link "symbolic link"
19567         mcreate_path2fid 0140666 0 0 sock "socket"
19568 }
19569 run_test 226a "call path2fid and fid2path on files of all type"
19570
19571 test_226b () {
19572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19573
19574         local MDTIDX=1
19575
19576         rm -rf $DIR/$tdir
19577         mkdir -p $DIR/$tdir
19578         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19579                 error "create remote directory failed"
19580         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19581         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19582                                 "character special file (null)"
19583         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19584                                 "character special file (no device)"
19585         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19586         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19587                                 "block special file (loop)"
19588         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19589         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19590         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19591 }
19592 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19593
19594 test_226c () {
19595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19596         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19597                 skip "Need MDS version at least 2.13.55"
19598
19599         local submnt=/mnt/submnt
19600         local srcfile=/etc/passwd
19601         local dstfile=$submnt/passwd
19602         local path
19603         local fid
19604
19605         rm -rf $DIR/$tdir
19606         rm -rf $submnt
19607         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19608                 error "create remote directory failed"
19609         mkdir -p $submnt || error "create $submnt failed"
19610         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19611                 error "mount $submnt failed"
19612         stack_trap "umount $submnt" EXIT
19613
19614         cp $srcfile $dstfile
19615         fid=$($LFS path2fid $dstfile)
19616         path=$($LFS fid2path $submnt "$fid")
19617         [ "$path" = "$dstfile" ] ||
19618                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19619 }
19620 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19621
19622 # LU-1299 Executing or running ldd on a truncated executable does not
19623 # cause an out-of-memory condition.
19624 test_227() {
19625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19626         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19627
19628         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19629         chmod +x $MOUNT/date
19630
19631         $MOUNT/date > /dev/null
19632         ldd $MOUNT/date > /dev/null
19633         rm -f $MOUNT/date
19634 }
19635 run_test 227 "running truncated executable does not cause OOM"
19636
19637 # LU-1512 try to reuse idle OI blocks
19638 test_228a() {
19639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19640         remote_mds_nodsh && skip "remote MDS with nodsh"
19641         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19642
19643         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19644         local myDIR=$DIR/$tdir
19645
19646         mkdir -p $myDIR
19647         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19648         $LCTL set_param fail_loc=0x80001002
19649         createmany -o $myDIR/t- 10000
19650         $LCTL set_param fail_loc=0
19651         # The guard is current the largest FID holder
19652         touch $myDIR/guard
19653         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19654                     tr -d '[')
19655         local IDX=$(($SEQ % 64))
19656
19657         do_facet $SINGLEMDS sync
19658         # Make sure journal flushed.
19659         sleep 6
19660         local blk1=$(do_facet $SINGLEMDS \
19661                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19662                      grep Blockcount | awk '{print $4}')
19663
19664         # Remove old files, some OI blocks will become idle.
19665         unlinkmany $myDIR/t- 10000
19666         # Create new files, idle OI blocks should be reused.
19667         createmany -o $myDIR/t- 2000
19668         do_facet $SINGLEMDS sync
19669         # Make sure journal flushed.
19670         sleep 6
19671         local blk2=$(do_facet $SINGLEMDS \
19672                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19673                      grep Blockcount | awk '{print $4}')
19674
19675         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19676 }
19677 run_test 228a "try to reuse idle OI blocks"
19678
19679 test_228b() {
19680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19681         remote_mds_nodsh && skip "remote MDS with nodsh"
19682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19683
19684         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19685         local myDIR=$DIR/$tdir
19686
19687         mkdir -p $myDIR
19688         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19689         $LCTL set_param fail_loc=0x80001002
19690         createmany -o $myDIR/t- 10000
19691         $LCTL set_param fail_loc=0
19692         # The guard is current the largest FID holder
19693         touch $myDIR/guard
19694         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19695                     tr -d '[')
19696         local IDX=$(($SEQ % 64))
19697
19698         do_facet $SINGLEMDS sync
19699         # Make sure journal flushed.
19700         sleep 6
19701         local blk1=$(do_facet $SINGLEMDS \
19702                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19703                      grep Blockcount | awk '{print $4}')
19704
19705         # Remove old files, some OI blocks will become idle.
19706         unlinkmany $myDIR/t- 10000
19707
19708         # stop the MDT
19709         stop $SINGLEMDS || error "Fail to stop MDT."
19710         # remount the MDT
19711         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19712                 error "Fail to start MDT."
19713
19714         df $MOUNT || error "Fail to df."
19715         # Create new files, idle OI blocks should be reused.
19716         createmany -o $myDIR/t- 2000
19717         do_facet $SINGLEMDS sync
19718         # Make sure journal flushed.
19719         sleep 6
19720         local blk2=$(do_facet $SINGLEMDS \
19721                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19722                      grep Blockcount | awk '{print $4}')
19723
19724         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19725 }
19726 run_test 228b "idle OI blocks can be reused after MDT restart"
19727
19728 #LU-1881
19729 test_228c() {
19730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19731         remote_mds_nodsh && skip "remote MDS with nodsh"
19732         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19733
19734         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19735         local myDIR=$DIR/$tdir
19736
19737         mkdir -p $myDIR
19738         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19739         $LCTL set_param fail_loc=0x80001002
19740         # 20000 files can guarantee there are index nodes in the OI file
19741         createmany -o $myDIR/t- 20000
19742         $LCTL set_param fail_loc=0
19743         # The guard is current the largest FID holder
19744         touch $myDIR/guard
19745         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19746                     tr -d '[')
19747         local IDX=$(($SEQ % 64))
19748
19749         do_facet $SINGLEMDS sync
19750         # Make sure journal flushed.
19751         sleep 6
19752         local blk1=$(do_facet $SINGLEMDS \
19753                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19754                      grep Blockcount | awk '{print $4}')
19755
19756         # Remove old files, some OI blocks will become idle.
19757         unlinkmany $myDIR/t- 20000
19758         rm -f $myDIR/guard
19759         # The OI file should become empty now
19760
19761         # Create new files, idle OI blocks should be reused.
19762         createmany -o $myDIR/t- 2000
19763         do_facet $SINGLEMDS sync
19764         # Make sure journal flushed.
19765         sleep 6
19766         local blk2=$(do_facet $SINGLEMDS \
19767                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19768                      grep Blockcount | awk '{print $4}')
19769
19770         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19771 }
19772 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19773
19774 test_229() { # LU-2482, LU-3448
19775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19776         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19777         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19778                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19779
19780         rm -f $DIR/$tfile
19781
19782         # Create a file with a released layout and stripe count 2.
19783         $MULTIOP $DIR/$tfile H2c ||
19784                 error "failed to create file with released layout"
19785
19786         $LFS getstripe -v $DIR/$tfile
19787
19788         local pattern=$($LFS getstripe -L $DIR/$tfile)
19789         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19790
19791         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19792                 error "getstripe"
19793         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19794         stat $DIR/$tfile || error "failed to stat released file"
19795
19796         chown $RUNAS_ID $DIR/$tfile ||
19797                 error "chown $RUNAS_ID $DIR/$tfile failed"
19798
19799         chgrp $RUNAS_ID $DIR/$tfile ||
19800                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19801
19802         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19803         rm $DIR/$tfile || error "failed to remove released file"
19804 }
19805 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19806
19807 test_230a() {
19808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19811                 skip "Need MDS version at least 2.11.52"
19812
19813         local MDTIDX=1
19814
19815         test_mkdir $DIR/$tdir
19816         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19817         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19818         [ $mdt_idx -ne 0 ] &&
19819                 error "create local directory on wrong MDT $mdt_idx"
19820
19821         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19822                         error "create remote directory failed"
19823         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19824         [ $mdt_idx -ne $MDTIDX ] &&
19825                 error "create remote directory on wrong MDT $mdt_idx"
19826
19827         createmany -o $DIR/$tdir/test_230/t- 10 ||
19828                 error "create files on remote directory failed"
19829         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19830         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19831         rm -r $DIR/$tdir || error "unlink remote directory failed"
19832 }
19833 run_test 230a "Create remote directory and files under the remote directory"
19834
19835 test_230b() {
19836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19838         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19839                 skip "Need MDS version at least 2.11.52"
19840
19841         local MDTIDX=1
19842         local mdt_index
19843         local i
19844         local file
19845         local pid
19846         local stripe_count
19847         local migrate_dir=$DIR/$tdir/migrate_dir
19848         local other_dir=$DIR/$tdir/other_dir
19849
19850         test_mkdir $DIR/$tdir
19851         test_mkdir -i0 -c1 $migrate_dir
19852         test_mkdir -i0 -c1 $other_dir
19853         for ((i=0; i<10; i++)); do
19854                 mkdir -p $migrate_dir/dir_${i}
19855                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19856                         error "create files under remote dir failed $i"
19857         done
19858
19859         cp /etc/passwd $migrate_dir/$tfile
19860         cp /etc/passwd $other_dir/$tfile
19861         chattr +SAD $migrate_dir
19862         chattr +SAD $migrate_dir/$tfile
19863
19864         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19865         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19866         local old_dir_mode=$(stat -c%f $migrate_dir)
19867         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19868
19869         mkdir -p $migrate_dir/dir_default_stripe2
19870         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19871         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19872
19873         mkdir -p $other_dir
19874         ln $migrate_dir/$tfile $other_dir/luna
19875         ln $migrate_dir/$tfile $migrate_dir/sofia
19876         ln $other_dir/$tfile $migrate_dir/david
19877         ln -s $migrate_dir/$tfile $other_dir/zachary
19878         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19879         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19880
19881         local len
19882         local lnktgt
19883
19884         # inline symlink
19885         for len in 58 59 60; do
19886                 lnktgt=$(str_repeat 'l' $len)
19887                 touch $migrate_dir/$lnktgt
19888                 ln -s $lnktgt $migrate_dir/${len}char_ln
19889         done
19890
19891         # PATH_MAX
19892         for len in 4094 4095; do
19893                 lnktgt=$(str_repeat 'l' $len)
19894                 ln -s $lnktgt $migrate_dir/${len}char_ln
19895         done
19896
19897         # NAME_MAX
19898         for len in 254 255; do
19899                 touch $migrate_dir/$(str_repeat 'l' $len)
19900         done
19901
19902         $LFS migrate -m $MDTIDX $migrate_dir ||
19903                 error "fails on migrating remote dir to MDT1"
19904
19905         echo "migratate to MDT1, then checking.."
19906         for ((i = 0; i < 10; i++)); do
19907                 for file in $(find $migrate_dir/dir_${i}); do
19908                         mdt_index=$($LFS getstripe -m $file)
19909                         # broken symlink getstripe will fail
19910                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19911                                 error "$file is not on MDT${MDTIDX}"
19912                 done
19913         done
19914
19915         # the multiple link file should still in MDT0
19916         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19917         [ $mdt_index == 0 ] ||
19918                 error "$file is not on MDT${MDTIDX}"
19919
19920         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19921         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19922                 error " expect $old_dir_flag get $new_dir_flag"
19923
19924         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19925         [ "$old_file_flag" = "$new_file_flag" ] ||
19926                 error " expect $old_file_flag get $new_file_flag"
19927
19928         local new_dir_mode=$(stat -c%f $migrate_dir)
19929         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19930                 error "expect mode $old_dir_mode get $new_dir_mode"
19931
19932         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19933         [ "$old_file_mode" = "$new_file_mode" ] ||
19934                 error "expect mode $old_file_mode get $new_file_mode"
19935
19936         diff /etc/passwd $migrate_dir/$tfile ||
19937                 error "$tfile different after migration"
19938
19939         diff /etc/passwd $other_dir/luna ||
19940                 error "luna different after migration"
19941
19942         diff /etc/passwd $migrate_dir/sofia ||
19943                 error "sofia different after migration"
19944
19945         diff /etc/passwd $migrate_dir/david ||
19946                 error "david different after migration"
19947
19948         diff /etc/passwd $other_dir/zachary ||
19949                 error "zachary different after migration"
19950
19951         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19952                 error "${tfile}_ln different after migration"
19953
19954         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19955                 error "${tfile}_ln_other different after migration"
19956
19957         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19958         [ $stripe_count = 2 ] ||
19959                 error "dir strpe_count $d != 2 after migration."
19960
19961         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19962         [ $stripe_count = 2 ] ||
19963                 error "file strpe_count $d != 2 after migration."
19964
19965         #migrate back to MDT0
19966         MDTIDX=0
19967
19968         $LFS migrate -m $MDTIDX $migrate_dir ||
19969                 error "fails on migrating remote dir to MDT0"
19970
19971         echo "migrate back to MDT0, checking.."
19972         for file in $(find $migrate_dir); do
19973                 mdt_index=$($LFS getstripe -m $file)
19974                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19975                         error "$file is not on MDT${MDTIDX}"
19976         done
19977
19978         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19979         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19980                 error " expect $old_dir_flag get $new_dir_flag"
19981
19982         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19983         [ "$old_file_flag" = "$new_file_flag" ] ||
19984                 error " expect $old_file_flag get $new_file_flag"
19985
19986         local new_dir_mode=$(stat -c%f $migrate_dir)
19987         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19988                 error "expect mode $old_dir_mode get $new_dir_mode"
19989
19990         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19991         [ "$old_file_mode" = "$new_file_mode" ] ||
19992                 error "expect mode $old_file_mode get $new_file_mode"
19993
19994         diff /etc/passwd ${migrate_dir}/$tfile ||
19995                 error "$tfile different after migration"
19996
19997         diff /etc/passwd ${other_dir}/luna ||
19998                 error "luna different after migration"
19999
20000         diff /etc/passwd ${migrate_dir}/sofia ||
20001                 error "sofia different after migration"
20002
20003         diff /etc/passwd ${other_dir}/zachary ||
20004                 error "zachary different after migration"
20005
20006         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20007                 error "${tfile}_ln different after migration"
20008
20009         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20010                 error "${tfile}_ln_other different after migration"
20011
20012         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20013         [ $stripe_count = 2 ] ||
20014                 error "dir strpe_count $d != 2 after migration."
20015
20016         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20017         [ $stripe_count = 2 ] ||
20018                 error "file strpe_count $d != 2 after migration."
20019
20020         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20021 }
20022 run_test 230b "migrate directory"
20023
20024 test_230c() {
20025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20027         remote_mds_nodsh && skip "remote MDS with nodsh"
20028         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20029                 skip "Need MDS version at least 2.11.52"
20030
20031         local MDTIDX=1
20032         local total=3
20033         local mdt_index
20034         local file
20035         local migrate_dir=$DIR/$tdir/migrate_dir
20036
20037         #If migrating directory fails in the middle, all entries of
20038         #the directory is still accessiable.
20039         test_mkdir $DIR/$tdir
20040         test_mkdir -i0 -c1 $migrate_dir
20041         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20042         stat $migrate_dir
20043         createmany -o $migrate_dir/f $total ||
20044                 error "create files under ${migrate_dir} failed"
20045
20046         # fail after migrating top dir, and this will fail only once, so the
20047         # first sub file migration will fail (currently f3), others succeed.
20048         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20049         do_facet mds1 lctl set_param fail_loc=0x1801
20050         local t=$(ls $migrate_dir | wc -l)
20051         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20052                 error "migrate should fail"
20053         local u=$(ls $migrate_dir | wc -l)
20054         [ "$u" == "$t" ] || error "$u != $t during migration"
20055
20056         # add new dir/file should succeed
20057         mkdir $migrate_dir/dir ||
20058                 error "mkdir failed under migrating directory"
20059         touch $migrate_dir/file ||
20060                 error "create file failed under migrating directory"
20061
20062         # add file with existing name should fail
20063         for file in $migrate_dir/f*; do
20064                 stat $file > /dev/null || error "stat $file failed"
20065                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20066                         error "open(O_CREAT|O_EXCL) $file should fail"
20067                 $MULTIOP $file m && error "create $file should fail"
20068                 touch $DIR/$tdir/remote_dir/$tfile ||
20069                         error "touch $tfile failed"
20070                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20071                         error "link $file should fail"
20072                 mdt_index=$($LFS getstripe -m $file)
20073                 if [ $mdt_index == 0 ]; then
20074                         # file failed to migrate is not allowed to rename to
20075                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20076                                 error "rename to $file should fail"
20077                 else
20078                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20079                                 error "rename to $file failed"
20080                 fi
20081                 echo hello >> $file || error "write $file failed"
20082         done
20083
20084         # resume migration with different options should fail
20085         $LFS migrate -m 0 $migrate_dir &&
20086                 error "migrate -m 0 $migrate_dir should fail"
20087
20088         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20089                 error "migrate -c 2 $migrate_dir should fail"
20090
20091         # resume migration should succeed
20092         $LFS migrate -m $MDTIDX $migrate_dir ||
20093                 error "migrate $migrate_dir failed"
20094
20095         echo "Finish migration, then checking.."
20096         for file in $(find $migrate_dir); do
20097                 mdt_index=$($LFS getstripe -m $file)
20098                 [ $mdt_index == $MDTIDX ] ||
20099                         error "$file is not on MDT${MDTIDX}"
20100         done
20101
20102         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20103 }
20104 run_test 230c "check directory accessiblity if migration failed"
20105
20106 test_230d() {
20107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20109         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20110                 skip "Need MDS version at least 2.11.52"
20111         # LU-11235
20112         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20113
20114         local migrate_dir=$DIR/$tdir/migrate_dir
20115         local old_index
20116         local new_index
20117         local old_count
20118         local new_count
20119         local new_hash
20120         local mdt_index
20121         local i
20122         local j
20123
20124         old_index=$((RANDOM % MDSCOUNT))
20125         old_count=$((MDSCOUNT - old_index))
20126         new_index=$((RANDOM % MDSCOUNT))
20127         new_count=$((MDSCOUNT - new_index))
20128         new_hash=1 # for all_char
20129
20130         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20131         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20132
20133         test_mkdir $DIR/$tdir
20134         test_mkdir -i $old_index -c $old_count $migrate_dir
20135
20136         for ((i=0; i<100; i++)); do
20137                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20138                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20139                         error "create files under remote dir failed $i"
20140         done
20141
20142         echo -n "Migrate from MDT$old_index "
20143         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20144         echo -n "to MDT$new_index"
20145         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20146         echo
20147
20148         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20149         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20150                 error "migrate remote dir error"
20151
20152         echo "Finish migration, then checking.."
20153         for file in $(find $migrate_dir -maxdepth 1); do
20154                 mdt_index=$($LFS getstripe -m $file)
20155                 if [ $mdt_index -lt $new_index ] ||
20156                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20157                         error "$file is on MDT$mdt_index"
20158                 fi
20159         done
20160
20161         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20162 }
20163 run_test 230d "check migrate big directory"
20164
20165 test_230e() {
20166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20169                 skip "Need MDS version at least 2.11.52"
20170
20171         local i
20172         local j
20173         local a_fid
20174         local b_fid
20175
20176         mkdir_on_mdt0 $DIR/$tdir
20177         mkdir $DIR/$tdir/migrate_dir
20178         mkdir $DIR/$tdir/other_dir
20179         touch $DIR/$tdir/migrate_dir/a
20180         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20181         ls $DIR/$tdir/other_dir
20182
20183         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20184                 error "migrate dir fails"
20185
20186         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20187         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20188
20189         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20190         [ $mdt_index == 0 ] || error "a is not on MDT0"
20191
20192         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20193                 error "migrate dir fails"
20194
20195         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20196         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20197
20198         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20199         [ $mdt_index == 1 ] || error "a is not on MDT1"
20200
20201         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20202         [ $mdt_index == 1 ] || error "b is not on MDT1"
20203
20204         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20205         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20206
20207         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20208
20209         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20210 }
20211 run_test 230e "migrate mulitple local link files"
20212
20213 test_230f() {
20214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20216         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20217                 skip "Need MDS version at least 2.11.52"
20218
20219         local a_fid
20220         local ln_fid
20221
20222         mkdir -p $DIR/$tdir
20223         mkdir $DIR/$tdir/migrate_dir
20224         $LFS mkdir -i1 $DIR/$tdir/other_dir
20225         touch $DIR/$tdir/migrate_dir/a
20226         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20227         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20228         ls $DIR/$tdir/other_dir
20229
20230         # a should be migrated to MDT1, since no other links on MDT0
20231         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20232                 error "#1 migrate dir fails"
20233         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20234         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20235         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20236         [ $mdt_index == 1 ] || error "a is not on MDT1"
20237
20238         # a should stay on MDT1, because it is a mulitple link file
20239         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20240                 error "#2 migrate dir fails"
20241         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20242         [ $mdt_index == 1 ] || error "a is not on MDT1"
20243
20244         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20245                 error "#3 migrate dir fails"
20246
20247         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20248         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20249         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20250
20251         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20252         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20253
20254         # a should be migrated to MDT0, since no other links on MDT1
20255         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20256                 error "#4 migrate dir fails"
20257         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20258         [ $mdt_index == 0 ] || error "a is not on MDT0"
20259
20260         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20261 }
20262 run_test 230f "migrate mulitple remote link files"
20263
20264 test_230g() {
20265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20267         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20268                 skip "Need MDS version at least 2.11.52"
20269
20270         mkdir -p $DIR/$tdir/migrate_dir
20271
20272         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20273                 error "migrating dir to non-exist MDT succeeds"
20274         true
20275 }
20276 run_test 230g "migrate dir to non-exist MDT"
20277
20278 test_230h() {
20279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20281         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20282                 skip "Need MDS version at least 2.11.52"
20283
20284         local mdt_index
20285
20286         mkdir -p $DIR/$tdir/migrate_dir
20287
20288         $LFS migrate -m1 $DIR &&
20289                 error "migrating mountpoint1 should fail"
20290
20291         $LFS migrate -m1 $DIR/$tdir/.. &&
20292                 error "migrating mountpoint2 should fail"
20293
20294         # same as mv
20295         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20296                 error "migrating $tdir/migrate_dir/.. should fail"
20297
20298         true
20299 }
20300 run_test 230h "migrate .. and root"
20301
20302 test_230i() {
20303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20305         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20306                 skip "Need MDS version at least 2.11.52"
20307
20308         mkdir -p $DIR/$tdir/migrate_dir
20309
20310         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20311                 error "migration fails with a tailing slash"
20312
20313         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20314                 error "migration fails with two tailing slashes"
20315 }
20316 run_test 230i "lfs migrate -m tolerates trailing slashes"
20317
20318 test_230j() {
20319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20320         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20321                 skip "Need MDS version at least 2.11.52"
20322
20323         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20324         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20325                 error "create $tfile failed"
20326         cat /etc/passwd > $DIR/$tdir/$tfile
20327
20328         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20329
20330         cmp /etc/passwd $DIR/$tdir/$tfile ||
20331                 error "DoM file mismatch after migration"
20332 }
20333 run_test 230j "DoM file data not changed after dir migration"
20334
20335 test_230k() {
20336         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20337         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20338                 skip "Need MDS version at least 2.11.56"
20339
20340         local total=20
20341         local files_on_starting_mdt=0
20342
20343         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20344         $LFS getdirstripe $DIR/$tdir
20345         for i in $(seq $total); do
20346                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20347                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20348                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20349         done
20350
20351         echo "$files_on_starting_mdt files on MDT0"
20352
20353         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20354         $LFS getdirstripe $DIR/$tdir
20355
20356         files_on_starting_mdt=0
20357         for i in $(seq $total); do
20358                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20359                         error "file $tfile.$i mismatch after migration"
20360                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20361                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20362         done
20363
20364         echo "$files_on_starting_mdt files on MDT1 after migration"
20365         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20366
20367         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20368         $LFS getdirstripe $DIR/$tdir
20369
20370         files_on_starting_mdt=0
20371         for i in $(seq $total); do
20372                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20373                         error "file $tfile.$i mismatch after 2nd migration"
20374                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20375                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20376         done
20377
20378         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20379         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20380
20381         true
20382 }
20383 run_test 230k "file data not changed after dir migration"
20384
20385 test_230l() {
20386         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20387         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20388                 skip "Need MDS version at least 2.11.56"
20389
20390         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20391         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20392                 error "create files under remote dir failed $i"
20393         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20394 }
20395 run_test 230l "readdir between MDTs won't crash"
20396
20397 test_230m() {
20398         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20399         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20400                 skip "Need MDS version at least 2.11.56"
20401
20402         local MDTIDX=1
20403         local mig_dir=$DIR/$tdir/migrate_dir
20404         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20405         local shortstr="b"
20406         local val
20407
20408         echo "Creating files and dirs with xattrs"
20409         test_mkdir $DIR/$tdir
20410         test_mkdir -i0 -c1 $mig_dir
20411         mkdir $mig_dir/dir
20412         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20413                 error "cannot set xattr attr1 on dir"
20414         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20415                 error "cannot set xattr attr2 on dir"
20416         touch $mig_dir/dir/f0
20417         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20418                 error "cannot set xattr attr1 on file"
20419         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20420                 error "cannot set xattr attr2 on file"
20421         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20422         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20423         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20424         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20425         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20426         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20427         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20428         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20429         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20430
20431         echo "Migrating to MDT1"
20432         $LFS migrate -m $MDTIDX $mig_dir ||
20433                 error "fails on migrating dir to MDT1"
20434
20435         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20436         echo "Checking xattrs"
20437         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20438         [ "$val" = $longstr ] ||
20439                 error "expecting xattr1 $longstr on dir, found $val"
20440         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20441         [ "$val" = $shortstr ] ||
20442                 error "expecting xattr2 $shortstr on dir, found $val"
20443         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20444         [ "$val" = $longstr ] ||
20445                 error "expecting xattr1 $longstr on file, found $val"
20446         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20447         [ "$val" = $shortstr ] ||
20448                 error "expecting xattr2 $shortstr on file, found $val"
20449 }
20450 run_test 230m "xattrs not changed after dir migration"
20451
20452 test_230n() {
20453         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20454         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20455                 skip "Need MDS version at least 2.13.53"
20456
20457         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20458         cat /etc/hosts > $DIR/$tdir/$tfile
20459         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20460         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20461
20462         cmp /etc/hosts $DIR/$tdir/$tfile ||
20463                 error "File data mismatch after migration"
20464 }
20465 run_test 230n "Dir migration with mirrored file"
20466
20467 test_230o() {
20468         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20469         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20470                 skip "Need MDS version at least 2.13.52"
20471
20472         local mdts=$(comma_list $(mdts_nodes))
20473         local timeout=100
20474         local restripe_status
20475         local delta
20476         local i
20477
20478         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20479
20480         # in case "crush" hash type is not set
20481         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20482
20483         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20484                            mdt.*MDT0000.enable_dir_restripe)
20485         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20486         stack_trap "do_nodes $mdts $LCTL set_param \
20487                     mdt.*.enable_dir_restripe=$restripe_status"
20488
20489         mkdir $DIR/$tdir
20490         createmany -m $DIR/$tdir/f 100 ||
20491                 error "create files under remote dir failed $i"
20492         createmany -d $DIR/$tdir/d 100 ||
20493                 error "create dirs under remote dir failed $i"
20494
20495         for i in $(seq 2 $MDSCOUNT); do
20496                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20497                 $LFS setdirstripe -c $i $DIR/$tdir ||
20498                         error "split -c $i $tdir failed"
20499                 wait_update $HOSTNAME \
20500                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20501                         error "dir split not finished"
20502                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20503                         awk '/migrate/ {sum += $2} END { print sum }')
20504                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20505                 # delta is around total_files/stripe_count
20506                 (( $delta < 200 / (i - 1) + 4 )) ||
20507                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20508         done
20509 }
20510 run_test 230o "dir split"
20511
20512 test_230p() {
20513         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20514         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20515                 skip "Need MDS version at least 2.13.52"
20516
20517         local mdts=$(comma_list $(mdts_nodes))
20518         local timeout=100
20519         local restripe_status
20520         local delta
20521         local c
20522
20523         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20524
20525         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20526
20527         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20528                            mdt.*MDT0000.enable_dir_restripe)
20529         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20530         stack_trap "do_nodes $mdts $LCTL set_param \
20531                     mdt.*.enable_dir_restripe=$restripe_status"
20532
20533         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20534         createmany -m $DIR/$tdir/f 100 ||
20535                 error "create files under remote dir failed"
20536         createmany -d $DIR/$tdir/d 100 ||
20537                 error "create dirs under remote dir failed"
20538
20539         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20540                 local mdt_hash="crush"
20541
20542                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20543                 $LFS setdirstripe -c $c $DIR/$tdir ||
20544                         error "split -c $c $tdir failed"
20545                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20546                         mdt_hash="$mdt_hash,fixed"
20547                 elif [ $c -eq 1 ]; then
20548                         mdt_hash="none"
20549                 fi
20550                 wait_update $HOSTNAME \
20551                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20552                         error "dir merge not finished"
20553                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20554                         awk '/migrate/ {sum += $2} END { print sum }')
20555                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20556                 # delta is around total_files/stripe_count
20557                 (( delta < 200 / c + 4 )) ||
20558                         error "$delta files migrated >= $((200 / c + 4))"
20559         done
20560 }
20561 run_test 230p "dir merge"
20562
20563 test_230q() {
20564         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20565         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20566                 skip "Need MDS version at least 2.13.52"
20567
20568         local mdts=$(comma_list $(mdts_nodes))
20569         local saved_threshold=$(do_facet mds1 \
20570                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20571         local saved_delta=$(do_facet mds1 \
20572                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20573         local threshold=100
20574         local delta=2
20575         local total=0
20576         local stripe_count=0
20577         local stripe_index
20578         local nr_files
20579         local create
20580
20581         # test with fewer files on ZFS
20582         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20583
20584         stack_trap "do_nodes $mdts $LCTL set_param \
20585                     mdt.*.dir_split_count=$saved_threshold"
20586         stack_trap "do_nodes $mdts $LCTL set_param \
20587                     mdt.*.dir_split_delta=$saved_delta"
20588         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20589         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20590         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20591         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20592         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20593         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20594
20595         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20596         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20597
20598         create=$((threshold * 3 / 2))
20599         while [ $stripe_count -lt $MDSCOUNT ]; do
20600                 createmany -m $DIR/$tdir/f $total $create ||
20601                         error "create sub files failed"
20602                 stat $DIR/$tdir > /dev/null
20603                 total=$((total + create))
20604                 stripe_count=$((stripe_count + delta))
20605                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20606
20607                 wait_update $HOSTNAME \
20608                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20609                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20610
20611                 wait_update $HOSTNAME \
20612                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20613                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20614
20615                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20616                 echo "$nr_files/$total files on MDT$stripe_index after split"
20617                 # allow 10% margin of imbalance with crush hash
20618                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20619                         error "$nr_files files on MDT$stripe_index after split"
20620
20621                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20622                 [ $nr_files -eq $total ] ||
20623                         error "total sub files $nr_files != $total"
20624         done
20625
20626         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20627
20628         echo "fixed layout directory won't auto split"
20629         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20630         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20631                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20632         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20633                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20634 }
20635 run_test 230q "dir auto split"
20636
20637 test_230r() {
20638         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20639         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20640         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20641                 skip "Need MDS version at least 2.13.54"
20642
20643         # maximum amount of local locks:
20644         # parent striped dir - 2 locks
20645         # new stripe in parent to migrate to - 1 lock
20646         # source and target - 2 locks
20647         # Total 5 locks for regular file
20648         mkdir -p $DIR/$tdir
20649         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20650         touch $DIR/$tdir/dir1/eee
20651
20652         # create 4 hardlink for 4 more locks
20653         # Total: 9 locks > RS_MAX_LOCKS (8)
20654         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20655         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20656         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20657         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20658         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20659         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20660         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20661         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20662
20663         cancel_lru_locks mdc
20664
20665         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20666                 error "migrate dir fails"
20667
20668         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20669 }
20670 run_test 230r "migrate with too many local locks"
20671
20672 test_230s() {
20673         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20674                 skip "Need MDS version at least 2.14.52"
20675
20676         local mdts=$(comma_list $(mdts_nodes))
20677         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20678                                 mdt.*MDT0000.enable_dir_restripe)
20679
20680         stack_trap "do_nodes $mdts $LCTL set_param \
20681                     mdt.*.enable_dir_restripe=$restripe_status"
20682
20683         local st
20684         for st in 0 1; do
20685                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20686                 test_mkdir $DIR/$tdir
20687                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20688                         error "$LFS mkdir should return EEXIST if target exists"
20689                 rmdir $DIR/$tdir
20690         done
20691 }
20692 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20693
20694 test_230t()
20695 {
20696         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20697         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20698                 skip "Need MDS version at least 2.14.50"
20699
20700         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20701         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20702         $LFS project -p 1 -s $DIR/$tdir ||
20703                 error "set $tdir project id failed"
20704         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20705                 error "set subdir project id failed"
20706         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20707 }
20708 run_test 230t "migrate directory with project ID set"
20709
20710 test_230u()
20711 {
20712         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20713         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20714                 skip "Need MDS version at least 2.14.53"
20715
20716         local count
20717
20718         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20719         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20720         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20721         for i in $(seq 0 $((MDSCOUNT - 1))); do
20722                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20723                 echo "$count dirs migrated to MDT$i"
20724         done
20725         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20726         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20727 }
20728 run_test 230u "migrate directory by QOS"
20729
20730 test_230v()
20731 {
20732         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20733         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20734                 skip "Need MDS version at least 2.14.53"
20735
20736         local count
20737
20738         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20739         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20740         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20741         for i in $(seq 0 $((MDSCOUNT - 1))); do
20742                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20743                 echo "$count subdirs migrated to MDT$i"
20744                 (( i == 3 )) && (( count > 0 )) &&
20745                         error "subdir shouldn't be migrated to MDT3"
20746         done
20747         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20748         (( count == 3 )) || error "dirs migrated to $count MDTs"
20749 }
20750 run_test 230v "subdir migrated to the MDT where its parent is located"
20751
20752 test_230w() {
20753         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20754         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20755                 skip "Need MDS version at least 2.15.0"
20756
20757         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20758         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20759         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20760
20761         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20762                 error "migrate failed"
20763
20764         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20765                 error "$tdir stripe count mismatch"
20766
20767         for i in $(seq 0 9); do
20768                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20769                         error "d$i is striped"
20770         done
20771 }
20772 run_test 230w "non-recursive mode dir migration"
20773
20774 test_231a()
20775 {
20776         # For simplicity this test assumes that max_pages_per_rpc
20777         # is the same across all OSCs
20778         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20779         local bulk_size=$((max_pages * PAGE_SIZE))
20780         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20781                                        head -n 1)
20782
20783         mkdir -p $DIR/$tdir
20784         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20785                 error "failed to set stripe with -S ${brw_size}M option"
20786
20787         # clear the OSC stats
20788         $LCTL set_param osc.*.stats=0 &>/dev/null
20789         stop_writeback
20790
20791         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20792         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20793                 oflag=direct &>/dev/null || error "dd failed"
20794
20795         sync; sleep 1; sync # just to be safe
20796         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20797         if [ x$nrpcs != "x1" ]; then
20798                 $LCTL get_param osc.*.stats
20799                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20800         fi
20801
20802         start_writeback
20803         # Drop the OSC cache, otherwise we will read from it
20804         cancel_lru_locks osc
20805
20806         # clear the OSC stats
20807         $LCTL set_param osc.*.stats=0 &>/dev/null
20808
20809         # Client reads $bulk_size.
20810         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20811                 iflag=direct &>/dev/null || error "dd failed"
20812
20813         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20814         if [ x$nrpcs != "x1" ]; then
20815                 $LCTL get_param osc.*.stats
20816                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20817         fi
20818 }
20819 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20820
20821 test_231b() {
20822         mkdir -p $DIR/$tdir
20823         local i
20824         for i in {0..1023}; do
20825                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20826                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20827                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20828         done
20829         sync
20830 }
20831 run_test 231b "must not assert on fully utilized OST request buffer"
20832
20833 test_232a() {
20834         mkdir -p $DIR/$tdir
20835         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20836
20837         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20838         do_facet ost1 $LCTL set_param fail_loc=0x31c
20839
20840         # ignore dd failure
20841         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20842
20843         do_facet ost1 $LCTL set_param fail_loc=0
20844         umount_client $MOUNT || error "umount failed"
20845         mount_client $MOUNT || error "mount failed"
20846         stop ost1 || error "cannot stop ost1"
20847         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20848 }
20849 run_test 232a "failed lock should not block umount"
20850
20851 test_232b() {
20852         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20853                 skip "Need MDS version at least 2.10.58"
20854
20855         mkdir -p $DIR/$tdir
20856         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20857         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20858         sync
20859         cancel_lru_locks osc
20860
20861         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20862         do_facet ost1 $LCTL set_param fail_loc=0x31c
20863
20864         # ignore failure
20865         $LFS data_version $DIR/$tdir/$tfile || true
20866
20867         do_facet ost1 $LCTL set_param fail_loc=0
20868         umount_client $MOUNT || error "umount failed"
20869         mount_client $MOUNT || error "mount failed"
20870         stop ost1 || error "cannot stop ost1"
20871         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20872 }
20873 run_test 232b "failed data version lock should not block umount"
20874
20875 test_233a() {
20876         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20877                 skip "Need MDS version at least 2.3.64"
20878         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20879
20880         local fid=$($LFS path2fid $MOUNT)
20881
20882         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20883                 error "cannot access $MOUNT using its FID '$fid'"
20884 }
20885 run_test 233a "checking that OBF of the FS root succeeds"
20886
20887 test_233b() {
20888         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20889                 skip "Need MDS version at least 2.5.90"
20890         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20891
20892         local fid=$($LFS path2fid $MOUNT/.lustre)
20893
20894         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20895                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20896
20897         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20898         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20899                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20900 }
20901 run_test 233b "checking that OBF of the FS .lustre succeeds"
20902
20903 test_234() {
20904         local p="$TMP/sanityN-$TESTNAME.parameters"
20905         save_lustre_params client "llite.*.xattr_cache" > $p
20906         lctl set_param llite.*.xattr_cache 1 ||
20907                 skip_env "xattr cache is not supported"
20908
20909         mkdir -p $DIR/$tdir || error "mkdir failed"
20910         touch $DIR/$tdir/$tfile || error "touch failed"
20911         # OBD_FAIL_LLITE_XATTR_ENOMEM
20912         $LCTL set_param fail_loc=0x1405
20913         getfattr -n user.attr $DIR/$tdir/$tfile &&
20914                 error "getfattr should have failed with ENOMEM"
20915         $LCTL set_param fail_loc=0x0
20916         rm -rf $DIR/$tdir
20917
20918         restore_lustre_params < $p
20919         rm -f $p
20920 }
20921 run_test 234 "xattr cache should not crash on ENOMEM"
20922
20923 test_235() {
20924         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20925                 skip "Need MDS version at least 2.4.52"
20926
20927         flock_deadlock $DIR/$tfile
20928         local RC=$?
20929         case $RC in
20930                 0)
20931                 ;;
20932                 124) error "process hangs on a deadlock"
20933                 ;;
20934                 *) error "error executing flock_deadlock $DIR/$tfile"
20935                 ;;
20936         esac
20937 }
20938 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20939
20940 #LU-2935
20941 test_236() {
20942         check_swap_layouts_support
20943
20944         local ref1=/etc/passwd
20945         local ref2=/etc/group
20946         local file1=$DIR/$tdir/f1
20947         local file2=$DIR/$tdir/f2
20948
20949         test_mkdir -c1 $DIR/$tdir
20950         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20951         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20952         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20953         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20954         local fd=$(free_fd)
20955         local cmd="exec $fd<>$file2"
20956         eval $cmd
20957         rm $file2
20958         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20959                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20960         cmd="exec $fd>&-"
20961         eval $cmd
20962         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20963
20964         #cleanup
20965         rm -rf $DIR/$tdir
20966 }
20967 run_test 236 "Layout swap on open unlinked file"
20968
20969 # LU-4659 linkea consistency
20970 test_238() {
20971         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20972                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20973                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20974                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20975
20976         touch $DIR/$tfile
20977         ln $DIR/$tfile $DIR/$tfile.lnk
20978         touch $DIR/$tfile.new
20979         mv $DIR/$tfile.new $DIR/$tfile
20980         local fid1=$($LFS path2fid $DIR/$tfile)
20981         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20982         local path1=$($LFS fid2path $FSNAME "$fid1")
20983         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20984         local path2=$($LFS fid2path $FSNAME "$fid2")
20985         [ $tfile.lnk == $path2 ] ||
20986                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20987         rm -f $DIR/$tfile*
20988 }
20989 run_test 238 "Verify linkea consistency"
20990
20991 test_239A() { # was test_239
20992         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20993                 skip "Need MDS version at least 2.5.60"
20994
20995         local list=$(comma_list $(mdts_nodes))
20996
20997         mkdir -p $DIR/$tdir
20998         createmany -o $DIR/$tdir/f- 5000
20999         unlinkmany $DIR/$tdir/f- 5000
21000         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21001                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21002         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21003                         osp.*MDT*.sync_in_flight" | calc_sum)
21004         [ "$changes" -eq 0 ] || error "$changes not synced"
21005 }
21006 run_test 239A "osp_sync test"
21007
21008 test_239a() { #LU-5297
21009         remote_mds_nodsh && skip "remote MDS with nodsh"
21010
21011         touch $DIR/$tfile
21012         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21013         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21014         chgrp $RUNAS_GID $DIR/$tfile
21015         wait_delete_completed
21016 }
21017 run_test 239a "process invalid osp sync record correctly"
21018
21019 test_239b() { #LU-5297
21020         remote_mds_nodsh && skip "remote MDS with nodsh"
21021
21022         touch $DIR/$tfile1
21023         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21024         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21025         chgrp $RUNAS_GID $DIR/$tfile1
21026         wait_delete_completed
21027         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21028         touch $DIR/$tfile2
21029         chgrp $RUNAS_GID $DIR/$tfile2
21030         wait_delete_completed
21031 }
21032 run_test 239b "process osp sync record with ENOMEM error correctly"
21033
21034 test_240() {
21035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21036         remote_mds_nodsh && skip "remote MDS with nodsh"
21037
21038         mkdir -p $DIR/$tdir
21039
21040         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21041                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21042         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21043                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21044
21045         umount_client $MOUNT || error "umount failed"
21046         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21047         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21048         mount_client $MOUNT || error "failed to mount client"
21049
21050         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21051         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21052 }
21053 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21054
21055 test_241_bio() {
21056         local count=$1
21057         local bsize=$2
21058
21059         for LOOP in $(seq $count); do
21060                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21061                 cancel_lru_locks $OSC || true
21062         done
21063 }
21064
21065 test_241_dio() {
21066         local count=$1
21067         local bsize=$2
21068
21069         for LOOP in $(seq $1); do
21070                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21071                         2>/dev/null
21072         done
21073 }
21074
21075 test_241a() { # was test_241
21076         local bsize=$PAGE_SIZE
21077
21078         (( bsize < 40960 )) && bsize=40960
21079         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21080         ls -la $DIR/$tfile
21081         cancel_lru_locks $OSC
21082         test_241_bio 1000 $bsize &
21083         PID=$!
21084         test_241_dio 1000 $bsize
21085         wait $PID
21086 }
21087 run_test 241a "bio vs dio"
21088
21089 test_241b() {
21090         local bsize=$PAGE_SIZE
21091
21092         (( bsize < 40960 )) && bsize=40960
21093         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21094         ls -la $DIR/$tfile
21095         test_241_dio 1000 $bsize &
21096         PID=$!
21097         test_241_dio 1000 $bsize
21098         wait $PID
21099 }
21100 run_test 241b "dio vs dio"
21101
21102 test_242() {
21103         remote_mds_nodsh && skip "remote MDS with nodsh"
21104
21105         mkdir_on_mdt0 $DIR/$tdir
21106         touch $DIR/$tdir/$tfile
21107
21108         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21109         do_facet mds1 lctl set_param fail_loc=0x105
21110         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21111
21112         do_facet mds1 lctl set_param fail_loc=0
21113         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21114 }
21115 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21116
21117 test_243()
21118 {
21119         test_mkdir $DIR/$tdir
21120         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21121 }
21122 run_test 243 "various group lock tests"
21123
21124 test_244a()
21125 {
21126         test_mkdir $DIR/$tdir
21127         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21128         sendfile_grouplock $DIR/$tdir/$tfile || \
21129                 error "sendfile+grouplock failed"
21130         rm -rf $DIR/$tdir
21131 }
21132 run_test 244a "sendfile with group lock tests"
21133
21134 test_244b()
21135 {
21136         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21137
21138         local threads=50
21139         local size=$((1024*1024))
21140
21141         test_mkdir $DIR/$tdir
21142         for i in $(seq 1 $threads); do
21143                 local file=$DIR/$tdir/file_$((i / 10))
21144                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21145                 local pids[$i]=$!
21146         done
21147         for i in $(seq 1 $threads); do
21148                 wait ${pids[$i]}
21149         done
21150 }
21151 run_test 244b "multi-threaded write with group lock"
21152
21153 test_245a() {
21154         local flagname="multi_mod_rpcs"
21155         local connect_data_name="max_mod_rpcs"
21156         local out
21157
21158         # check if multiple modify RPCs flag is set
21159         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21160                 grep "connect_flags:")
21161         echo "$out"
21162
21163         echo "$out" | grep -qw $flagname
21164         if [ $? -ne 0 ]; then
21165                 echo "connect flag $flagname is not set"
21166                 return
21167         fi
21168
21169         # check if multiple modify RPCs data is set
21170         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21171         echo "$out"
21172
21173         echo "$out" | grep -qw $connect_data_name ||
21174                 error "import should have connect data $connect_data_name"
21175 }
21176 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21177
21178 test_245b() {
21179         local flagname="multi_mod_rpcs"
21180         local connect_data_name="max_mod_rpcs"
21181         local out
21182
21183         remote_mds_nodsh && skip "remote MDS with nodsh"
21184         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21185
21186         # check if multiple modify RPCs flag is set
21187         out=$(do_facet mds1 \
21188               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21189               grep "connect_flags:")
21190         echo "$out"
21191
21192         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21193
21194         # check if multiple modify RPCs data is set
21195         out=$(do_facet mds1 \
21196               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21197
21198         [[ "$out" =~ $connect_data_name ]] ||
21199                 {
21200                         echo "$out"
21201                         error "missing connect data $connect_data_name"
21202                 }
21203 }
21204 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21205
21206 cleanup_247() {
21207         local submount=$1
21208
21209         trap 0
21210         umount_client $submount
21211         rmdir $submount
21212 }
21213
21214 test_247a() {
21215         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21216                 grep -q subtree ||
21217                 skip_env "Fileset feature is not supported"
21218
21219         local submount=${MOUNT}_$tdir
21220
21221         mkdir $MOUNT/$tdir
21222         mkdir -p $submount || error "mkdir $submount failed"
21223         FILESET="$FILESET/$tdir" mount_client $submount ||
21224                 error "mount $submount failed"
21225         trap "cleanup_247 $submount" EXIT
21226         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21227         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21228                 error "read $MOUNT/$tdir/$tfile failed"
21229         cleanup_247 $submount
21230 }
21231 run_test 247a "mount subdir as fileset"
21232
21233 test_247b() {
21234         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21235                 skip_env "Fileset feature is not supported"
21236
21237         local submount=${MOUNT}_$tdir
21238
21239         rm -rf $MOUNT/$tdir
21240         mkdir -p $submount || error "mkdir $submount failed"
21241         SKIP_FILESET=1
21242         FILESET="$FILESET/$tdir" mount_client $submount &&
21243                 error "mount $submount should fail"
21244         rmdir $submount
21245 }
21246 run_test 247b "mount subdir that dose not exist"
21247
21248 test_247c() {
21249         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21250                 skip_env "Fileset feature is not supported"
21251
21252         local submount=${MOUNT}_$tdir
21253
21254         mkdir -p $MOUNT/$tdir/dir1
21255         mkdir -p $submount || error "mkdir $submount failed"
21256         trap "cleanup_247 $submount" EXIT
21257         FILESET="$FILESET/$tdir" mount_client $submount ||
21258                 error "mount $submount failed"
21259         local fid=$($LFS path2fid $MOUNT/)
21260         $LFS fid2path $submount $fid && error "fid2path should fail"
21261         cleanup_247 $submount
21262 }
21263 run_test 247c "running fid2path outside subdirectory root"
21264
21265 test_247d() {
21266         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21267                 skip "Fileset feature is not supported"
21268
21269         local submount=${MOUNT}_$tdir
21270
21271         mkdir -p $MOUNT/$tdir/dir1
21272         mkdir -p $submount || error "mkdir $submount failed"
21273         FILESET="$FILESET/$tdir" mount_client $submount ||
21274                 error "mount $submount failed"
21275         trap "cleanup_247 $submount" EXIT
21276
21277         local td=$submount/dir1
21278         local fid=$($LFS path2fid $td)
21279         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21280
21281         # check that we get the same pathname back
21282         local rootpath
21283         local found
21284         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21285                 echo "$rootpath $fid"
21286                 found=$($LFS fid2path $rootpath "$fid")
21287                 [ -n "$found" ] || error "fid2path should succeed"
21288                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21289         done
21290         # check wrong root path format
21291         rootpath=$submount"_wrong"
21292         found=$($LFS fid2path $rootpath "$fid")
21293         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21294
21295         cleanup_247 $submount
21296 }
21297 run_test 247d "running fid2path inside subdirectory root"
21298
21299 # LU-8037
21300 test_247e() {
21301         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21302                 grep -q subtree ||
21303                 skip "Fileset feature is not supported"
21304
21305         local submount=${MOUNT}_$tdir
21306
21307         mkdir $MOUNT/$tdir
21308         mkdir -p $submount || error "mkdir $submount failed"
21309         FILESET="$FILESET/.." mount_client $submount &&
21310                 error "mount $submount should fail"
21311         rmdir $submount
21312 }
21313 run_test 247e "mount .. as fileset"
21314
21315 test_247f() {
21316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21317         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21318                 skip "Need at least version 2.13.52"
21319         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21320                 skip "Need at least version 2.14.50"
21321         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21322                 grep -q subtree ||
21323                 skip "Fileset feature is not supported"
21324
21325         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21326         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21327                 error "mkdir remote failed"
21328         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21329                 error "mkdir remote/subdir failed"
21330         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21331                 error "mkdir striped failed"
21332         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21333
21334         local submount=${MOUNT}_$tdir
21335
21336         mkdir -p $submount || error "mkdir $submount failed"
21337         stack_trap "rmdir $submount"
21338
21339         local dir
21340         local stat
21341         local fileset=$FILESET
21342         local mdts=$(comma_list $(mdts_nodes))
21343
21344         stat=$(do_facet mds1 $LCTL get_param -n \
21345                 mdt.*MDT0000.enable_remote_subdir_mount)
21346         stack_trap "do_nodes $mdts $LCTL set_param \
21347                 mdt.*.enable_remote_subdir_mount=$stat"
21348
21349         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21350         stack_trap "umount_client $submount"
21351         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21352                 error "mount remote dir $dir should fail"
21353
21354         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21355                 $tdir/striped/. ; do
21356                 FILESET="$fileset/$dir" mount_client $submount ||
21357                         error "mount $dir failed"
21358                 umount_client $submount
21359         done
21360
21361         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21362         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21363                 error "mount $tdir/remote failed"
21364 }
21365 run_test 247f "mount striped or remote directory as fileset"
21366
21367 test_247g() {
21368         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21369         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21370                 skip "Need at least version 2.14.50"
21371
21372         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21373                 error "mkdir $tdir failed"
21374         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21375
21376         local submount=${MOUNT}_$tdir
21377
21378         mkdir -p $submount || error "mkdir $submount failed"
21379         stack_trap "rmdir $submount"
21380
21381         FILESET="$fileset/$tdir" mount_client $submount ||
21382                 error "mount $dir failed"
21383         stack_trap "umount $submount"
21384
21385         local mdts=$(comma_list $(mdts_nodes))
21386
21387         local nrpcs
21388
21389         stat $submount > /dev/null
21390         cancel_lru_locks $MDC
21391         stat $submount > /dev/null
21392         stat $submount/$tfile > /dev/null
21393         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21394         stat $submount/$tfile > /dev/null
21395         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21396                 awk '/getattr/ {sum += $2} END {print sum}')
21397
21398         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21399 }
21400 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21401
21402 test_248a() {
21403         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21404         [ -z "$fast_read_sav" ] && skip "no fast read support"
21405
21406         # create a large file for fast read verification
21407         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21408
21409         # make sure the file is created correctly
21410         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21411                 { rm -f $DIR/$tfile; skip "file creation error"; }
21412
21413         echo "Test 1: verify that fast read is 4 times faster on cache read"
21414
21415         # small read with fast read enabled
21416         $LCTL set_param -n llite.*.fast_read=1
21417         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21418                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21419                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21420         # small read with fast read disabled
21421         $LCTL set_param -n llite.*.fast_read=0
21422         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21423                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21424                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21425
21426         # verify that fast read is 4 times faster for cache read
21427         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21428                 error_not_in_vm "fast read was not 4 times faster: " \
21429                            "$t_fast vs $t_slow"
21430
21431         echo "Test 2: verify the performance between big and small read"
21432         $LCTL set_param -n llite.*.fast_read=1
21433
21434         # 1k non-cache read
21435         cancel_lru_locks osc
21436         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21437                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21438                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21439
21440         # 1M non-cache read
21441         cancel_lru_locks osc
21442         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21443                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21444                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21445
21446         # verify that big IO is not 4 times faster than small IO
21447         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21448                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21449
21450         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21451         rm -f $DIR/$tfile
21452 }
21453 run_test 248a "fast read verification"
21454
21455 test_248b() {
21456         # Default short_io_bytes=16384, try both smaller and larger sizes.
21457         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21458         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21459         echo "bs=53248 count=113 normal buffered write"
21460         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21461                 error "dd of initial data file failed"
21462         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21463
21464         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21465         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21466                 error "dd with sync normal writes failed"
21467         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21468
21469         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21470         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21471                 error "dd with sync small writes failed"
21472         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21473
21474         cancel_lru_locks osc
21475
21476         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21477         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21478         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21479         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21480                 iflag=direct || error "dd with O_DIRECT small read failed"
21481         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21482         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21483                 error "compare $TMP/$tfile.1 failed"
21484
21485         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21486         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21487
21488         # just to see what the maximum tunable value is, and test parsing
21489         echo "test invalid parameter 2MB"
21490         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21491                 error "too-large short_io_bytes allowed"
21492         echo "test maximum parameter 512KB"
21493         # if we can set a larger short_io_bytes, run test regardless of version
21494         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21495                 # older clients may not allow setting it this large, that's OK
21496                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21497                         skip "Need at least client version 2.13.50"
21498                 error "medium short_io_bytes failed"
21499         fi
21500         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21501         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21502
21503         echo "test large parameter 64KB"
21504         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21505         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21506
21507         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21508         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21509                 error "dd with sync large writes failed"
21510         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21511
21512         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21513         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21514         num=$((113 * 4096 / PAGE_SIZE))
21515         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21516         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21517                 error "dd with O_DIRECT large writes failed"
21518         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21519                 error "compare $DIR/$tfile.3 failed"
21520
21521         cancel_lru_locks osc
21522
21523         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21524         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21525                 error "dd with O_DIRECT large read failed"
21526         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21527                 error "compare $TMP/$tfile.2 failed"
21528
21529         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21530         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21531                 error "dd with O_DIRECT large read failed"
21532         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21533                 error "compare $TMP/$tfile.3 failed"
21534 }
21535 run_test 248b "test short_io read and write for both small and large sizes"
21536
21537 test_249() { # LU-7890
21538         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21539                 skip "Need at least version 2.8.54"
21540
21541         rm -f $DIR/$tfile
21542         $LFS setstripe -c 1 $DIR/$tfile
21543         # Offset 2T == 4k * 512M
21544         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21545                 error "dd to 2T offset failed"
21546 }
21547 run_test 249 "Write above 2T file size"
21548
21549 test_250() {
21550         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21551          && skip "no 16TB file size limit on ZFS"
21552
21553         $LFS setstripe -c 1 $DIR/$tfile
21554         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21555         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21556         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21557         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21558                 conv=notrunc,fsync && error "append succeeded"
21559         return 0
21560 }
21561 run_test 250 "Write above 16T limit"
21562
21563 test_251() {
21564         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21565
21566         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21567         #Skip once - writing the first stripe will succeed
21568         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21569         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21570                 error "short write happened"
21571
21572         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21573         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21574                 error "short read happened"
21575
21576         rm -f $DIR/$tfile
21577 }
21578 run_test 251 "Handling short read and write correctly"
21579
21580 test_252() {
21581         remote_mds_nodsh && skip "remote MDS with nodsh"
21582         remote_ost_nodsh && skip "remote OST with nodsh"
21583         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21584                 skip_env "ldiskfs only test"
21585         fi
21586
21587         local tgt
21588         local dev
21589         local out
21590         local uuid
21591         local num
21592         local gen
21593
21594         # check lr_reader on OST0000
21595         tgt=ost1
21596         dev=$(facet_device $tgt)
21597         out=$(do_facet $tgt $LR_READER $dev)
21598         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21599         echo "$out"
21600         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21601         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21602                 error "Invalid uuid returned by $LR_READER on target $tgt"
21603         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21604
21605         # check lr_reader -c on MDT0000
21606         tgt=mds1
21607         dev=$(facet_device $tgt)
21608         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21609                 skip "$LR_READER does not support additional options"
21610         fi
21611         out=$(do_facet $tgt $LR_READER -c $dev)
21612         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21613         echo "$out"
21614         num=$(echo "$out" | grep -c "mdtlov")
21615         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21616                 error "Invalid number of mdtlov clients returned by $LR_READER"
21617         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21618
21619         # check lr_reader -cr on MDT0000
21620         out=$(do_facet $tgt $LR_READER -cr $dev)
21621         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21622         echo "$out"
21623         echo "$out" | grep -q "^reply_data:$" ||
21624                 error "$LR_READER should have returned 'reply_data' section"
21625         num=$(echo "$out" | grep -c "client_generation")
21626         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21627 }
21628 run_test 252 "check lr_reader tool"
21629
21630 test_253() {
21631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21632         remote_mds_nodsh && skip "remote MDS with nodsh"
21633         remote_mgs_nodsh && skip "remote MGS with nodsh"
21634
21635         local ostidx=0
21636         local rc=0
21637         local ost_name=$(ostname_from_index $ostidx)
21638
21639         # on the mdt's osc
21640         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21641         do_facet $SINGLEMDS $LCTL get_param -n \
21642                 osp.$mdtosc_proc1.reserved_mb_high ||
21643                 skip  "remote MDS does not support reserved_mb_high"
21644
21645         rm -rf $DIR/$tdir
21646         wait_mds_ost_sync
21647         wait_delete_completed
21648         mkdir $DIR/$tdir
21649
21650         pool_add $TESTNAME || error "Pool creation failed"
21651         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21652
21653         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21654                 error "Setstripe failed"
21655
21656         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21657
21658         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21659                     grep "watermarks")
21660         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21661
21662         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21663                         osp.$mdtosc_proc1.prealloc_status)
21664         echo "prealloc_status $oa_status"
21665
21666         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21667                 error "File creation should fail"
21668
21669         #object allocation was stopped, but we still able to append files
21670         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21671                 oflag=append || error "Append failed"
21672
21673         rm -f $DIR/$tdir/$tfile.0
21674
21675         # For this test, we want to delete the files we created to go out of
21676         # space but leave the watermark, so we remain nearly out of space
21677         ost_watermarks_enospc_delete_files $tfile $ostidx
21678
21679         wait_delete_completed
21680
21681         sleep_maxage
21682
21683         for i in $(seq 10 12); do
21684                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21685                         2>/dev/null || error "File creation failed after rm"
21686         done
21687
21688         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21689                         osp.$mdtosc_proc1.prealloc_status)
21690         echo "prealloc_status $oa_status"
21691
21692         if (( oa_status != 0 )); then
21693                 error "Object allocation still disable after rm"
21694         fi
21695 }
21696 run_test 253 "Check object allocation limit"
21697
21698 test_254() {
21699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21700         remote_mds_nodsh && skip "remote MDS with nodsh"
21701
21702         local mdt=$(facet_svc $SINGLEMDS)
21703
21704         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21705                 skip "MDS does not support changelog_size"
21706
21707         local cl_user
21708
21709         changelog_register || error "changelog_register failed"
21710
21711         changelog_clear 0 || error "changelog_clear failed"
21712
21713         local size1=$(do_facet $SINGLEMDS \
21714                       $LCTL get_param -n mdd.$mdt.changelog_size)
21715         echo "Changelog size $size1"
21716
21717         rm -rf $DIR/$tdir
21718         $LFS mkdir -i 0 $DIR/$tdir
21719         # change something
21720         mkdir -p $DIR/$tdir/pics/2008/zachy
21721         touch $DIR/$tdir/pics/2008/zachy/timestamp
21722         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21723         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21724         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21725         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21726         rm $DIR/$tdir/pics/desktop.jpg
21727
21728         local size2=$(do_facet $SINGLEMDS \
21729                       $LCTL get_param -n mdd.$mdt.changelog_size)
21730         echo "Changelog size after work $size2"
21731
21732         (( $size2 > $size1 )) ||
21733                 error "new Changelog size=$size2 less than old size=$size1"
21734 }
21735 run_test 254 "Check changelog size"
21736
21737 ladvise_no_type()
21738 {
21739         local type=$1
21740         local file=$2
21741
21742         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21743                 awk -F: '{print $2}' | grep $type > /dev/null
21744         if [ $? -ne 0 ]; then
21745                 return 0
21746         fi
21747         return 1
21748 }
21749
21750 ladvise_no_ioctl()
21751 {
21752         local file=$1
21753
21754         lfs ladvise -a willread $file > /dev/null 2>&1
21755         if [ $? -eq 0 ]; then
21756                 return 1
21757         fi
21758
21759         lfs ladvise -a willread $file 2>&1 |
21760                 grep "Inappropriate ioctl for device" > /dev/null
21761         if [ $? -eq 0 ]; then
21762                 return 0
21763         fi
21764         return 1
21765 }
21766
21767 percent() {
21768         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21769 }
21770
21771 # run a random read IO workload
21772 # usage: random_read_iops <filename> <filesize> <iosize>
21773 random_read_iops() {
21774         local file=$1
21775         local fsize=$2
21776         local iosize=${3:-4096}
21777
21778         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21779                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21780 }
21781
21782 drop_file_oss_cache() {
21783         local file="$1"
21784         local nodes="$2"
21785
21786         $LFS ladvise -a dontneed $file 2>/dev/null ||
21787                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21788 }
21789
21790 ladvise_willread_performance()
21791 {
21792         local repeat=10
21793         local average_origin=0
21794         local average_cache=0
21795         local average_ladvise=0
21796
21797         for ((i = 1; i <= $repeat; i++)); do
21798                 echo "Iter $i/$repeat: reading without willread hint"
21799                 cancel_lru_locks osc
21800                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21801                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21802                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21803                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21804
21805                 cancel_lru_locks osc
21806                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21807                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21808                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21809
21810                 cancel_lru_locks osc
21811                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21812                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21813                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21814                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21815                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21816         done
21817         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21818         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21819         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21820
21821         speedup_cache=$(percent $average_cache $average_origin)
21822         speedup_ladvise=$(percent $average_ladvise $average_origin)
21823
21824         echo "Average uncached read: $average_origin"
21825         echo "Average speedup with OSS cached read: " \
21826                 "$average_cache = +$speedup_cache%"
21827         echo "Average speedup with ladvise willread: " \
21828                 "$average_ladvise = +$speedup_ladvise%"
21829
21830         local lowest_speedup=20
21831         if (( ${average_cache%.*} < $lowest_speedup )); then
21832                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21833                      " got $average_cache%. Skipping ladvise willread check."
21834                 return 0
21835         fi
21836
21837         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21838         # it is still good to run until then to exercise 'ladvise willread'
21839         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21840                 [ "$ost1_FSTYPE" = "zfs" ] &&
21841                 echo "osd-zfs does not support dontneed or drop_caches" &&
21842                 return 0
21843
21844         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21845         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21846                 error_not_in_vm "Speedup with willread is less than " \
21847                         "$lowest_speedup%, got $average_ladvise%"
21848 }
21849
21850 test_255a() {
21851         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21852                 skip "lustre < 2.8.54 does not support ladvise "
21853         remote_ost_nodsh && skip "remote OST with nodsh"
21854
21855         stack_trap "rm -f $DIR/$tfile"
21856         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21857
21858         ladvise_no_type willread $DIR/$tfile &&
21859                 skip "willread ladvise is not supported"
21860
21861         ladvise_no_ioctl $DIR/$tfile &&
21862                 skip "ladvise ioctl is not supported"
21863
21864         local size_mb=100
21865         local size=$((size_mb * 1048576))
21866         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21867                 error "dd to $DIR/$tfile failed"
21868
21869         lfs ladvise -a willread $DIR/$tfile ||
21870                 error "Ladvise failed with no range argument"
21871
21872         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21873                 error "Ladvise failed with no -l or -e argument"
21874
21875         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21876                 error "Ladvise failed with only -e argument"
21877
21878         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21879                 error "Ladvise failed with only -l argument"
21880
21881         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21882                 error "End offset should not be smaller than start offset"
21883
21884         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21885                 error "End offset should not be equal to start offset"
21886
21887         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21888                 error "Ladvise failed with overflowing -s argument"
21889
21890         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21891                 error "Ladvise failed with overflowing -e argument"
21892
21893         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21894                 error "Ladvise failed with overflowing -l argument"
21895
21896         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21897                 error "Ladvise succeeded with conflicting -l and -e arguments"
21898
21899         echo "Synchronous ladvise should wait"
21900         local delay=4
21901 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21902         do_nodes $(comma_list $(osts_nodes)) \
21903                 $LCTL set_param fail_val=$delay fail_loc=0x237
21904
21905         local start_ts=$SECONDS
21906         lfs ladvise -a willread $DIR/$tfile ||
21907                 error "Ladvise failed with no range argument"
21908         local end_ts=$SECONDS
21909         local inteval_ts=$((end_ts - start_ts))
21910
21911         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21912                 error "Synchronous advice didn't wait reply"
21913         fi
21914
21915         echo "Asynchronous ladvise shouldn't wait"
21916         local start_ts=$SECONDS
21917         lfs ladvise -a willread -b $DIR/$tfile ||
21918                 error "Ladvise failed with no range argument"
21919         local end_ts=$SECONDS
21920         local inteval_ts=$((end_ts - start_ts))
21921
21922         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21923                 error "Asynchronous advice blocked"
21924         fi
21925
21926         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21927         ladvise_willread_performance
21928 }
21929 run_test 255a "check 'lfs ladvise -a willread'"
21930
21931 facet_meminfo() {
21932         local facet=$1
21933         local info=$2
21934
21935         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21936 }
21937
21938 test_255b() {
21939         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21940                 skip "lustre < 2.8.54 does not support ladvise "
21941         remote_ost_nodsh && skip "remote OST with nodsh"
21942
21943         stack_trap "rm -f $DIR/$tfile"
21944         lfs setstripe -c 1 -i 0 $DIR/$tfile
21945
21946         ladvise_no_type dontneed $DIR/$tfile &&
21947                 skip "dontneed ladvise is not supported"
21948
21949         ladvise_no_ioctl $DIR/$tfile &&
21950                 skip "ladvise ioctl is not supported"
21951
21952         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21953                 [ "$ost1_FSTYPE" = "zfs" ] &&
21954                 skip "zfs-osd does not support 'ladvise dontneed'"
21955
21956         local size_mb=100
21957         local size=$((size_mb * 1048576))
21958         # In order to prevent disturbance of other processes, only check 3/4
21959         # of the memory usage
21960         local kibibytes=$((size_mb * 1024 * 3 / 4))
21961
21962         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21963                 error "dd to $DIR/$tfile failed"
21964
21965         #force write to complete before dropping OST cache & checking memory
21966         sync
21967
21968         local total=$(facet_meminfo ost1 MemTotal)
21969         echo "Total memory: $total KiB"
21970
21971         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21972         local before_read=$(facet_meminfo ost1 Cached)
21973         echo "Cache used before read: $before_read KiB"
21974
21975         lfs ladvise -a willread $DIR/$tfile ||
21976                 error "Ladvise willread failed"
21977         local after_read=$(facet_meminfo ost1 Cached)
21978         echo "Cache used after read: $after_read KiB"
21979
21980         lfs ladvise -a dontneed $DIR/$tfile ||
21981                 error "Ladvise dontneed again failed"
21982         local no_read=$(facet_meminfo ost1 Cached)
21983         echo "Cache used after dontneed ladvise: $no_read KiB"
21984
21985         if [ $total -lt $((before_read + kibibytes)) ]; then
21986                 echo "Memory is too small, abort checking"
21987                 return 0
21988         fi
21989
21990         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21991                 error "Ladvise willread should use more memory" \
21992                         "than $kibibytes KiB"
21993         fi
21994
21995         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21996                 error "Ladvise dontneed should release more memory" \
21997                         "than $kibibytes KiB"
21998         fi
21999 }
22000 run_test 255b "check 'lfs ladvise -a dontneed'"
22001
22002 test_255c() {
22003         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22004                 skip "lustre < 2.10.50 does not support lockahead"
22005
22006         local ost1_imp=$(get_osc_import_name client ost1)
22007         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22008                          cut -d'.' -f2)
22009         local count
22010         local new_count
22011         local difference
22012         local i
22013         local rc
22014
22015         test_mkdir -p $DIR/$tdir
22016         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22017
22018         #test 10 returns only success/failure
22019         i=10
22020         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22021         rc=$?
22022         if [ $rc -eq 255 ]; then
22023                 error "Ladvise test${i} failed, ${rc}"
22024         fi
22025
22026         #test 11 counts lock enqueue requests, all others count new locks
22027         i=11
22028         count=$(do_facet ost1 \
22029                 $LCTL get_param -n ost.OSS.ost.stats)
22030         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22031
22032         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22033         rc=$?
22034         if [ $rc -eq 255 ]; then
22035                 error "Ladvise test${i} failed, ${rc}"
22036         fi
22037
22038         new_count=$(do_facet ost1 \
22039                 $LCTL get_param -n ost.OSS.ost.stats)
22040         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22041                    awk '{ print $2 }')
22042
22043         difference="$((new_count - count))"
22044         if [ $difference -ne $rc ]; then
22045                 error "Ladvise test${i}, bad enqueue count, returned " \
22046                       "${rc}, actual ${difference}"
22047         fi
22048
22049         for i in $(seq 12 21); do
22050                 # If we do not do this, we run the risk of having too many
22051                 # locks and starting lock cancellation while we are checking
22052                 # lock counts.
22053                 cancel_lru_locks osc
22054
22055                 count=$($LCTL get_param -n \
22056                        ldlm.namespaces.$imp_name.lock_unused_count)
22057
22058                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22059                 rc=$?
22060                 if [ $rc -eq 255 ]; then
22061                         error "Ladvise test ${i} failed, ${rc}"
22062                 fi
22063
22064                 new_count=$($LCTL get_param -n \
22065                        ldlm.namespaces.$imp_name.lock_unused_count)
22066                 difference="$((new_count - count))"
22067
22068                 # Test 15 output is divided by 100 to map down to valid return
22069                 if [ $i -eq 15 ]; then
22070                         rc="$((rc * 100))"
22071                 fi
22072
22073                 if [ $difference -ne $rc ]; then
22074                         error "Ladvise test ${i}, bad lock count, returned " \
22075                               "${rc}, actual ${difference}"
22076                 fi
22077         done
22078
22079         #test 22 returns only success/failure
22080         i=22
22081         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22082         rc=$?
22083         if [ $rc -eq 255 ]; then
22084                 error "Ladvise test${i} failed, ${rc}"
22085         fi
22086 }
22087 run_test 255c "suite of ladvise lockahead tests"
22088
22089 test_256() {
22090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22091         remote_mds_nodsh && skip "remote MDS with nodsh"
22092         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22093         changelog_users $SINGLEMDS | grep "^cl" &&
22094                 skip "active changelog user"
22095
22096         local cl_user
22097         local cat_sl
22098         local mdt_dev
22099
22100         mdt_dev=$(facet_device $SINGLEMDS)
22101         echo $mdt_dev
22102
22103         changelog_register || error "changelog_register failed"
22104
22105         rm -rf $DIR/$tdir
22106         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22107
22108         changelog_clear 0 || error "changelog_clear failed"
22109
22110         # change something
22111         touch $DIR/$tdir/{1..10}
22112
22113         # stop the MDT
22114         stop $SINGLEMDS || error "Fail to stop MDT"
22115
22116         # remount the MDT
22117         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22118                 error "Fail to start MDT"
22119
22120         #after mount new plainllog is used
22121         touch $DIR/$tdir/{11..19}
22122         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22123         stack_trap "rm -f $tmpfile"
22124         cat_sl=$(do_facet $SINGLEMDS "sync; \
22125                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22126                  llog_reader $tmpfile | grep -c type=1064553b")
22127         do_facet $SINGLEMDS llog_reader $tmpfile
22128
22129         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22130
22131         changelog_clear 0 || error "changelog_clear failed"
22132
22133         cat_sl=$(do_facet $SINGLEMDS "sync; \
22134                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22135                  llog_reader $tmpfile | grep -c type=1064553b")
22136
22137         if (( cat_sl == 2 )); then
22138                 error "Empty plain llog was not deleted from changelog catalog"
22139         elif (( cat_sl != 1 )); then
22140                 error "Active plain llog shouldn't be deleted from catalog"
22141         fi
22142 }
22143 run_test 256 "Check llog delete for empty and not full state"
22144
22145 test_257() {
22146         remote_mds_nodsh && skip "remote MDS with nodsh"
22147         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22148                 skip "Need MDS version at least 2.8.55"
22149
22150         test_mkdir $DIR/$tdir
22151
22152         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22153                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22154         stat $DIR/$tdir
22155
22156 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22157         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22158         local facet=mds$((mdtidx + 1))
22159         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22160         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22161
22162         stop $facet || error "stop MDS failed"
22163         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22164                 error "start MDS fail"
22165         wait_recovery_complete $facet
22166 }
22167 run_test 257 "xattr locks are not lost"
22168
22169 # Verify we take the i_mutex when security requires it
22170 test_258a() {
22171 #define OBD_FAIL_IMUTEX_SEC 0x141c
22172         $LCTL set_param fail_loc=0x141c
22173         touch $DIR/$tfile
22174         chmod u+s $DIR/$tfile
22175         chmod a+rwx $DIR/$tfile
22176         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22177         RC=$?
22178         if [ $RC -ne 0 ]; then
22179                 error "error, failed to take i_mutex, rc=$?"
22180         fi
22181         rm -f $DIR/$tfile
22182 }
22183 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22184
22185 # Verify we do NOT take the i_mutex in the normal case
22186 test_258b() {
22187 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22188         $LCTL set_param fail_loc=0x141d
22189         touch $DIR/$tfile
22190         chmod a+rwx $DIR
22191         chmod a+rw $DIR/$tfile
22192         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22193         RC=$?
22194         if [ $RC -ne 0 ]; then
22195                 error "error, took i_mutex unnecessarily, rc=$?"
22196         fi
22197         rm -f $DIR/$tfile
22198
22199 }
22200 run_test 258b "verify i_mutex security behavior"
22201
22202 test_259() {
22203         local file=$DIR/$tfile
22204         local before
22205         local after
22206
22207         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22208
22209         stack_trap "rm -f $file" EXIT
22210
22211         wait_delete_completed
22212         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22213         echo "before: $before"
22214
22215         $LFS setstripe -i 0 -c 1 $file
22216         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22217         sync_all_data
22218         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22219         echo "after write: $after"
22220
22221 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22222         do_facet ost1 $LCTL set_param fail_loc=0x2301
22223         $TRUNCATE $file 0
22224         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22225         echo "after truncate: $after"
22226
22227         stop ost1
22228         do_facet ost1 $LCTL set_param fail_loc=0
22229         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22230         sleep 2
22231         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22232         echo "after restart: $after"
22233         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22234                 error "missing truncate?"
22235
22236         return 0
22237 }
22238 run_test 259 "crash at delayed truncate"
22239
22240 test_260() {
22241 #define OBD_FAIL_MDC_CLOSE               0x806
22242         $LCTL set_param fail_loc=0x80000806
22243         touch $DIR/$tfile
22244
22245 }
22246 run_test 260 "Check mdc_close fail"
22247
22248 ### Data-on-MDT sanity tests ###
22249 test_270a() {
22250         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22251                 skip "Need MDS version at least 2.10.55 for DoM"
22252
22253         # create DoM file
22254         local dom=$DIR/$tdir/dom_file
22255         local tmp=$DIR/$tdir/tmp_file
22256
22257         mkdir_on_mdt0 $DIR/$tdir
22258
22259         # basic checks for DoM component creation
22260         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22261                 error "Can set MDT layout to non-first entry"
22262
22263         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22264                 error "Can define multiple entries as MDT layout"
22265
22266         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22267
22268         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22269         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22270         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22271
22272         local mdtidx=$($LFS getstripe -m $dom)
22273         local mdtname=MDT$(printf %04x $mdtidx)
22274         local facet=mds$((mdtidx + 1))
22275         local space_check=1
22276
22277         # Skip free space checks with ZFS
22278         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22279
22280         # write
22281         sync
22282         local size_tmp=$((65536 * 3))
22283         local mdtfree1=$(do_facet $facet \
22284                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22285
22286         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22287         # check also direct IO along write
22288         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22289         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22290         sync
22291         cmp $tmp $dom || error "file data is different"
22292         [ $(stat -c%s $dom) == $size_tmp ] ||
22293                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22294         if [ $space_check == 1 ]; then
22295                 local mdtfree2=$(do_facet $facet \
22296                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22297
22298                 # increase in usage from by $size_tmp
22299                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22300                         error "MDT free space wrong after write: " \
22301                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22302         fi
22303
22304         # truncate
22305         local size_dom=10000
22306
22307         $TRUNCATE $dom $size_dom
22308         [ $(stat -c%s $dom) == $size_dom ] ||
22309                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22310         if [ $space_check == 1 ]; then
22311                 mdtfree1=$(do_facet $facet \
22312                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22313                 # decrease in usage from $size_tmp to new $size_dom
22314                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22315                   $(((size_tmp - size_dom) / 1024)) ] ||
22316                         error "MDT free space is wrong after truncate: " \
22317                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22318         fi
22319
22320         # append
22321         cat $tmp >> $dom
22322         sync
22323         size_dom=$((size_dom + size_tmp))
22324         [ $(stat -c%s $dom) == $size_dom ] ||
22325                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22326         if [ $space_check == 1 ]; then
22327                 mdtfree2=$(do_facet $facet \
22328                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22329                 # increase in usage by $size_tmp from previous
22330                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22331                         error "MDT free space is wrong after append: " \
22332                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22333         fi
22334
22335         # delete
22336         rm $dom
22337         if [ $space_check == 1 ]; then
22338                 mdtfree1=$(do_facet $facet \
22339                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22340                 # decrease in usage by $size_dom from previous
22341                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22342                         error "MDT free space is wrong after removal: " \
22343                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22344         fi
22345
22346         # combined striping
22347         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22348                 error "Can't create DoM + OST striping"
22349
22350         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22351         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22352         # check also direct IO along write
22353         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22354         sync
22355         cmp $tmp $dom || error "file data is different"
22356         [ $(stat -c%s $dom) == $size_tmp ] ||
22357                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22358         rm $dom $tmp
22359
22360         return 0
22361 }
22362 run_test 270a "DoM: basic functionality tests"
22363
22364 test_270b() {
22365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22366                 skip "Need MDS version at least 2.10.55"
22367
22368         local dom=$DIR/$tdir/dom_file
22369         local max_size=1048576
22370
22371         mkdir -p $DIR/$tdir
22372         $LFS setstripe -E $max_size -L mdt $dom
22373
22374         # truncate over the limit
22375         $TRUNCATE $dom $(($max_size + 1)) &&
22376                 error "successful truncate over the maximum size"
22377         # write over the limit
22378         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22379                 error "successful write over the maximum size"
22380         # append over the limit
22381         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22382         echo "12345" >> $dom && error "successful append over the maximum size"
22383         rm $dom
22384
22385         return 0
22386 }
22387 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22388
22389 test_270c() {
22390         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22391                 skip "Need MDS version at least 2.10.55"
22392
22393         mkdir -p $DIR/$tdir
22394         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22395
22396         # check files inherit DoM EA
22397         touch $DIR/$tdir/first
22398         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22399                 error "bad pattern"
22400         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22401                 error "bad stripe count"
22402         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22403                 error "bad stripe size"
22404
22405         # check directory inherits DoM EA and uses it as default
22406         mkdir $DIR/$tdir/subdir
22407         touch $DIR/$tdir/subdir/second
22408         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22409                 error "bad pattern in sub-directory"
22410         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22411                 error "bad stripe count in sub-directory"
22412         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22413                 error "bad stripe size in sub-directory"
22414         return 0
22415 }
22416 run_test 270c "DoM: DoM EA inheritance tests"
22417
22418 test_270d() {
22419         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22420                 skip "Need MDS version at least 2.10.55"
22421
22422         mkdir -p $DIR/$tdir
22423         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22424
22425         # inherit default DoM striping
22426         mkdir $DIR/$tdir/subdir
22427         touch $DIR/$tdir/subdir/f1
22428
22429         # change default directory striping
22430         $LFS setstripe -c 1 $DIR/$tdir/subdir
22431         touch $DIR/$tdir/subdir/f2
22432         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22433                 error "wrong default striping in file 2"
22434         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22435                 error "bad pattern in file 2"
22436         return 0
22437 }
22438 run_test 270d "DoM: change striping from DoM to RAID0"
22439
22440 test_270e() {
22441         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22442                 skip "Need MDS version at least 2.10.55"
22443
22444         mkdir -p $DIR/$tdir/dom
22445         mkdir -p $DIR/$tdir/norm
22446         DOMFILES=20
22447         NORMFILES=10
22448         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22449         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22450
22451         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22452         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22453
22454         # find DoM files by layout
22455         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22456         [ $NUM -eq  $DOMFILES ] ||
22457                 error "lfs find -L: found $NUM, expected $DOMFILES"
22458         echo "Test 1: lfs find 20 DOM files by layout: OK"
22459
22460         # there should be 1 dir with default DOM striping
22461         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22462         [ $NUM -eq  1 ] ||
22463                 error "lfs find -L: found $NUM, expected 1 dir"
22464         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22465
22466         # find DoM files by stripe size
22467         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22468         [ $NUM -eq  $DOMFILES ] ||
22469                 error "lfs find -S: found $NUM, expected $DOMFILES"
22470         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22471
22472         # find files by stripe offset except DoM files
22473         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22474         [ $NUM -eq  $NORMFILES ] ||
22475                 error "lfs find -i: found $NUM, expected $NORMFILES"
22476         echo "Test 5: lfs find no DOM files by stripe index: OK"
22477         return 0
22478 }
22479 run_test 270e "DoM: lfs find with DoM files test"
22480
22481 test_270f() {
22482         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22483                 skip "Need MDS version at least 2.10.55"
22484
22485         local mdtname=${FSNAME}-MDT0000-mdtlov
22486         local dom=$DIR/$tdir/dom_file
22487         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22488                                                 lod.$mdtname.dom_stripesize)
22489         local dom_limit=131072
22490
22491         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22492         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22493                                                 lod.$mdtname.dom_stripesize)
22494         [ ${dom_limit} -eq ${dom_current} ] ||
22495                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22496
22497         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22498         $LFS setstripe -d $DIR/$tdir
22499         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22500                 error "Can't set directory default striping"
22501
22502         # exceed maximum stripe size
22503         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22504                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22505         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22506                 error "Able to create DoM component size more than LOD limit"
22507
22508         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22509         dom_current=$(do_facet mds1 $LCTL get_param -n \
22510                                                 lod.$mdtname.dom_stripesize)
22511         [ 0 -eq ${dom_current} ] ||
22512                 error "Can't set zero DoM stripe limit"
22513         rm $dom
22514
22515         # attempt to create DoM file on server with disabled DoM should
22516         # remove DoM entry from layout and be succeed
22517         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22518                 error "Can't create DoM file (DoM is disabled)"
22519         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22520                 error "File has DoM component while DoM is disabled"
22521         rm $dom
22522
22523         # attempt to create DoM file with only DoM stripe should return error
22524         $LFS setstripe -E $dom_limit -L mdt $dom &&
22525                 error "Able to create DoM-only file while DoM is disabled"
22526
22527         # too low values to be aligned with smallest stripe size 64K
22528         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22529         dom_current=$(do_facet mds1 $LCTL get_param -n \
22530                                                 lod.$mdtname.dom_stripesize)
22531         [ 30000 -eq ${dom_current} ] &&
22532                 error "Can set too small DoM stripe limit"
22533
22534         # 64K is a minimal stripe size in Lustre, expect limit of that size
22535         [ 65536 -eq ${dom_current} ] ||
22536                 error "Limit is not set to 64K but ${dom_current}"
22537
22538         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22539         dom_current=$(do_facet mds1 $LCTL get_param -n \
22540                                                 lod.$mdtname.dom_stripesize)
22541         echo $dom_current
22542         [ 2147483648 -eq ${dom_current} ] &&
22543                 error "Can set too large DoM stripe limit"
22544
22545         do_facet mds1 $LCTL set_param -n \
22546                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22547         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22548                 error "Can't create DoM component size after limit change"
22549         do_facet mds1 $LCTL set_param -n \
22550                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22551         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22552                 error "Can't create DoM file after limit decrease"
22553         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22554                 error "Can create big DoM component after limit decrease"
22555         touch ${dom}_def ||
22556                 error "Can't create file with old default layout"
22557
22558         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22559         return 0
22560 }
22561 run_test 270f "DoM: maximum DoM stripe size checks"
22562
22563 test_270g() {
22564         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22565                 skip "Need MDS version at least 2.13.52"
22566         local dom=$DIR/$tdir/$tfile
22567
22568         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22569         local lodname=${FSNAME}-MDT0000-mdtlov
22570
22571         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22572         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22573         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22574         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22575
22576         local dom_limit=1024
22577         local dom_threshold="50%"
22578
22579         $LFS setstripe -d $DIR/$tdir
22580         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22581                 error "Can't set directory default striping"
22582
22583         do_facet mds1 $LCTL set_param -n \
22584                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22585         # set 0 threshold and create DOM file to change tunable stripesize
22586         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22587         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22588                 error "Failed to create $dom file"
22589         # now tunable dom_cur_stripesize should reach maximum
22590         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22591                                         lod.${lodname}.dom_stripesize_cur_kb)
22592         [[ $dom_current == $dom_limit ]] ||
22593                 error "Current DOM stripesize is not maximum"
22594         rm $dom
22595
22596         # set threshold for further tests
22597         do_facet mds1 $LCTL set_param -n \
22598                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22599         echo "DOM threshold is $dom_threshold free space"
22600         local dom_def
22601         local dom_set
22602         # Spoof bfree to exceed threshold
22603         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22604         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22605         for spfree in 40 20 0 15 30 55; do
22606                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22607                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22608                         error "Failed to create $dom file"
22609                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22610                                         lod.${lodname}.dom_stripesize_cur_kb)
22611                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22612                 [[ $dom_def != $dom_current ]] ||
22613                         error "Default stripe size was not changed"
22614                 if (( spfree > 0 )) ; then
22615                         dom_set=$($LFS getstripe -S $dom)
22616                         (( dom_set == dom_def * 1024 )) ||
22617                                 error "DOM component size is still old"
22618                 else
22619                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22620                                 error "DoM component is set with no free space"
22621                 fi
22622                 rm $dom
22623                 dom_current=$dom_def
22624         done
22625 }
22626 run_test 270g "DoM: default DoM stripe size depends on free space"
22627
22628 test_270h() {
22629         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22630                 skip "Need MDS version at least 2.13.53"
22631
22632         local mdtname=${FSNAME}-MDT0000-mdtlov
22633         local dom=$DIR/$tdir/$tfile
22634         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22635
22636         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22637         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22638
22639         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22640         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22641                 error "can't create OST file"
22642         # mirrored file with DOM entry in the second mirror
22643         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22644                 error "can't create mirror with DoM component"
22645
22646         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22647
22648         # DOM component in the middle and has other enries in the same mirror,
22649         # should succeed but lost DoM component
22650         $LFS setstripe --copy=${dom}_1 $dom ||
22651                 error "Can't create file from OST|DOM mirror layout"
22652         # check new file has no DoM layout after all
22653         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22654                 error "File has DoM component while DoM is disabled"
22655 }
22656 run_test 270h "DoM: DoM stripe removal when disabled on server"
22657
22658 test_270i() {
22659         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22660                 skip "Need MDS version at least 2.14.54"
22661
22662         mkdir $DIR/$tdir
22663         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22664                 error "setstripe should fail" || true
22665 }
22666 run_test 270i "DoM: setting invalid DoM striping should fail"
22667
22668 test_271a() {
22669         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22670                 skip "Need MDS version at least 2.10.55"
22671
22672         local dom=$DIR/$tdir/dom
22673
22674         mkdir -p $DIR/$tdir
22675
22676         $LFS setstripe -E 1024K -L mdt $dom
22677
22678         lctl set_param -n mdc.*.stats=clear
22679         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22680         cat $dom > /dev/null
22681         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22682         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22683         ls $dom
22684         rm -f $dom
22685 }
22686 run_test 271a "DoM: data is cached for read after write"
22687
22688 test_271b() {
22689         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22690                 skip "Need MDS version at least 2.10.55"
22691
22692         local dom=$DIR/$tdir/dom
22693
22694         mkdir -p $DIR/$tdir
22695
22696         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22697
22698         lctl set_param -n mdc.*.stats=clear
22699         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22700         cancel_lru_locks mdc
22701         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22702         # second stat to check size is cached on client
22703         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22704         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22705         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22706         rm -f $dom
22707 }
22708 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22709
22710 test_271ba() {
22711         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22712                 skip "Need MDS version at least 2.10.55"
22713
22714         local dom=$DIR/$tdir/dom
22715
22716         mkdir -p $DIR/$tdir
22717
22718         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22719
22720         lctl set_param -n mdc.*.stats=clear
22721         lctl set_param -n osc.*.stats=clear
22722         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22723         cancel_lru_locks mdc
22724         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22725         # second stat to check size is cached on client
22726         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22727         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22728         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22729         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22730         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22731         rm -f $dom
22732 }
22733 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22734
22735
22736 get_mdc_stats() {
22737         local mdtidx=$1
22738         local param=$2
22739         local mdt=MDT$(printf %04x $mdtidx)
22740
22741         if [ -z $param ]; then
22742                 lctl get_param -n mdc.*$mdt*.stats
22743         else
22744                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22745         fi
22746 }
22747
22748 test_271c() {
22749         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22750                 skip "Need MDS version at least 2.10.55"
22751
22752         local dom=$DIR/$tdir/dom
22753
22754         mkdir -p $DIR/$tdir
22755
22756         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22757
22758         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22759         local facet=mds$((mdtidx + 1))
22760
22761         cancel_lru_locks mdc
22762         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22763         createmany -o $dom 1000
22764         lctl set_param -n mdc.*.stats=clear
22765         smalliomany -w $dom 1000 200
22766         get_mdc_stats $mdtidx
22767         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22768         # Each file has 1 open, 1 IO enqueues, total 2000
22769         # but now we have also +1 getxattr for security.capability, total 3000
22770         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22771         unlinkmany $dom 1000
22772
22773         cancel_lru_locks mdc
22774         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22775         createmany -o $dom 1000
22776         lctl set_param -n mdc.*.stats=clear
22777         smalliomany -w $dom 1000 200
22778         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22779         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22780         # for OPEN and IO lock.
22781         [ $((enq - enq_2)) -ge 1000 ] ||
22782                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22783         unlinkmany $dom 1000
22784         return 0
22785 }
22786 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22787
22788 cleanup_271def_tests() {
22789         trap 0
22790         rm -f $1
22791 }
22792
22793 test_271d() {
22794         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22795                 skip "Need MDS version at least 2.10.57"
22796
22797         local dom=$DIR/$tdir/dom
22798         local tmp=$TMP/$tfile
22799         trap "cleanup_271def_tests $tmp" EXIT
22800
22801         mkdir -p $DIR/$tdir
22802
22803         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22804
22805         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22806
22807         cancel_lru_locks mdc
22808         dd if=/dev/urandom of=$tmp bs=1000 count=1
22809         dd if=$tmp of=$dom bs=1000 count=1
22810         cancel_lru_locks mdc
22811
22812         cat /etc/hosts >> $tmp
22813         lctl set_param -n mdc.*.stats=clear
22814
22815         # append data to the same file it should update local page
22816         echo "Append to the same page"
22817         cat /etc/hosts >> $dom
22818         local num=$(get_mdc_stats $mdtidx ost_read)
22819         local ra=$(get_mdc_stats $mdtidx req_active)
22820         local rw=$(get_mdc_stats $mdtidx req_waittime)
22821
22822         [ -z $num ] || error "$num READ RPC occured"
22823         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22824         echo "... DONE"
22825
22826         # compare content
22827         cmp $tmp $dom || error "file miscompare"
22828
22829         cancel_lru_locks mdc
22830         lctl set_param -n mdc.*.stats=clear
22831
22832         echo "Open and read file"
22833         cat $dom > /dev/null
22834         local num=$(get_mdc_stats $mdtidx ost_read)
22835         local ra=$(get_mdc_stats $mdtidx req_active)
22836         local rw=$(get_mdc_stats $mdtidx req_waittime)
22837
22838         [ -z $num ] || error "$num READ RPC occured"
22839         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22840         echo "... DONE"
22841
22842         # compare content
22843         cmp $tmp $dom || error "file miscompare"
22844
22845         return 0
22846 }
22847 run_test 271d "DoM: read on open (1K file in reply buffer)"
22848
22849 test_271f() {
22850         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22851                 skip "Need MDS version at least 2.10.57"
22852
22853         local dom=$DIR/$tdir/dom
22854         local tmp=$TMP/$tfile
22855         trap "cleanup_271def_tests $tmp" EXIT
22856
22857         mkdir -p $DIR/$tdir
22858
22859         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22860
22861         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22862
22863         cancel_lru_locks mdc
22864         dd if=/dev/urandom of=$tmp bs=265000 count=1
22865         dd if=$tmp of=$dom bs=265000 count=1
22866         cancel_lru_locks mdc
22867         cat /etc/hosts >> $tmp
22868         lctl set_param -n mdc.*.stats=clear
22869
22870         echo "Append to the same page"
22871         cat /etc/hosts >> $dom
22872         local num=$(get_mdc_stats $mdtidx ost_read)
22873         local ra=$(get_mdc_stats $mdtidx req_active)
22874         local rw=$(get_mdc_stats $mdtidx req_waittime)
22875
22876         [ -z $num ] || error "$num READ RPC occured"
22877         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22878         echo "... DONE"
22879
22880         # compare content
22881         cmp $tmp $dom || error "file miscompare"
22882
22883         cancel_lru_locks mdc
22884         lctl set_param -n mdc.*.stats=clear
22885
22886         echo "Open and read file"
22887         cat $dom > /dev/null
22888         local num=$(get_mdc_stats $mdtidx ost_read)
22889         local ra=$(get_mdc_stats $mdtidx req_active)
22890         local rw=$(get_mdc_stats $mdtidx req_waittime)
22891
22892         [ -z $num ] && num=0
22893         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22894         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22895         echo "... DONE"
22896
22897         # compare content
22898         cmp $tmp $dom || error "file miscompare"
22899
22900         return 0
22901 }
22902 run_test 271f "DoM: read on open (200K file and read tail)"
22903
22904 test_271g() {
22905         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22906                 skip "Skipping due to old client or server version"
22907
22908         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22909         # to get layout
22910         $CHECKSTAT -t file $DIR1/$tfile
22911
22912         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22913         MULTIOP_PID=$!
22914         sleep 1
22915         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22916         $LCTL set_param fail_loc=0x80000314
22917         rm $DIR1/$tfile || error "Unlink fails"
22918         RC=$?
22919         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22920         [ $RC -eq 0 ] || error "Failed write to stale object"
22921 }
22922 run_test 271g "Discard DoM data vs client flush race"
22923
22924 test_272a() {
22925         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22926                 skip "Need MDS version at least 2.11.50"
22927
22928         local dom=$DIR/$tdir/dom
22929         mkdir -p $DIR/$tdir
22930
22931         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22932         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22933                 error "failed to write data into $dom"
22934         local old_md5=$(md5sum $dom)
22935
22936         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22937                 error "failed to migrate to the same DoM component"
22938
22939         local new_md5=$(md5sum $dom)
22940
22941         [ "$old_md5" == "$new_md5" ] ||
22942                 error "md5sum differ: $old_md5, $new_md5"
22943
22944         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22945                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22946 }
22947 run_test 272a "DoM migration: new layout with the same DOM component"
22948
22949 test_272b() {
22950         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22951                 skip "Need MDS version at least 2.11.50"
22952
22953         local dom=$DIR/$tdir/dom
22954         mkdir -p $DIR/$tdir
22955         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22956
22957         local mdtidx=$($LFS getstripe -m $dom)
22958         local mdtname=MDT$(printf %04x $mdtidx)
22959         local facet=mds$((mdtidx + 1))
22960
22961         local mdtfree1=$(do_facet $facet \
22962                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22963         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22964                 error "failed to write data into $dom"
22965         local old_md5=$(md5sum $dom)
22966         cancel_lru_locks mdc
22967         local mdtfree1=$(do_facet $facet \
22968                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22969
22970         $LFS migrate -c2 $dom ||
22971                 error "failed to migrate to the new composite layout"
22972         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22973                 error "MDT stripe was not removed"
22974
22975         cancel_lru_locks mdc
22976         local new_md5=$(md5sum $dom)
22977         [ "$old_md5" == "$new_md5" ] ||
22978                 error "$old_md5 != $new_md5"
22979
22980         # Skip free space checks with ZFS
22981         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22982                 local mdtfree2=$(do_facet $facet \
22983                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22984                 [ $mdtfree2 -gt $mdtfree1 ] ||
22985                         error "MDT space is not freed after migration"
22986         fi
22987         return 0
22988 }
22989 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22990
22991 test_272c() {
22992         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22993                 skip "Need MDS version at least 2.11.50"
22994
22995         local dom=$DIR/$tdir/$tfile
22996         mkdir -p $DIR/$tdir
22997         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22998
22999         local mdtidx=$($LFS getstripe -m $dom)
23000         local mdtname=MDT$(printf %04x $mdtidx)
23001         local facet=mds$((mdtidx + 1))
23002
23003         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23004                 error "failed to write data into $dom"
23005         local old_md5=$(md5sum $dom)
23006         cancel_lru_locks mdc
23007         local mdtfree1=$(do_facet $facet \
23008                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23009
23010         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23011                 error "failed to migrate to the new composite layout"
23012         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23013                 error "MDT stripe was not removed"
23014
23015         cancel_lru_locks mdc
23016         local new_md5=$(md5sum $dom)
23017         [ "$old_md5" == "$new_md5" ] ||
23018                 error "$old_md5 != $new_md5"
23019
23020         # Skip free space checks with ZFS
23021         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23022                 local mdtfree2=$(do_facet $facet \
23023                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23024                 [ $mdtfree2 -gt $mdtfree1 ] ||
23025                         error "MDS space is not freed after migration"
23026         fi
23027         return 0
23028 }
23029 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23030
23031 test_272d() {
23032         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23033                 skip "Need MDS version at least 2.12.55"
23034
23035         local dom=$DIR/$tdir/$tfile
23036         mkdir -p $DIR/$tdir
23037         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23038
23039         local mdtidx=$($LFS getstripe -m $dom)
23040         local mdtname=MDT$(printf %04x $mdtidx)
23041         local facet=mds$((mdtidx + 1))
23042
23043         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23044                 error "failed to write data into $dom"
23045         local old_md5=$(md5sum $dom)
23046         cancel_lru_locks mdc
23047         local mdtfree1=$(do_facet $facet \
23048                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23049
23050         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23051                 error "failed mirroring to the new composite layout"
23052         $LFS mirror resync $dom ||
23053                 error "failed mirror resync"
23054         $LFS mirror split --mirror-id 1 -d $dom ||
23055                 error "failed mirror split"
23056
23057         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23058                 error "MDT stripe was not removed"
23059
23060         cancel_lru_locks mdc
23061         local new_md5=$(md5sum $dom)
23062         [ "$old_md5" == "$new_md5" ] ||
23063                 error "$old_md5 != $new_md5"
23064
23065         # Skip free space checks with ZFS
23066         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23067                 local mdtfree2=$(do_facet $facet \
23068                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23069                 [ $mdtfree2 -gt $mdtfree1 ] ||
23070                         error "MDS space is not freed after DOM mirror deletion"
23071         fi
23072         return 0
23073 }
23074 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23075
23076 test_272e() {
23077         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23078                 skip "Need MDS version at least 2.12.55"
23079
23080         local dom=$DIR/$tdir/$tfile
23081         mkdir -p $DIR/$tdir
23082         $LFS setstripe -c 2 $dom
23083
23084         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23085                 error "failed to write data into $dom"
23086         local old_md5=$(md5sum $dom)
23087         cancel_lru_locks
23088
23089         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23090                 error "failed mirroring to the DOM layout"
23091         $LFS mirror resync $dom ||
23092                 error "failed mirror resync"
23093         $LFS mirror split --mirror-id 1 -d $dom ||
23094                 error "failed mirror split"
23095
23096         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23097                 error "MDT stripe wasn't set"
23098
23099         cancel_lru_locks
23100         local new_md5=$(md5sum $dom)
23101         [ "$old_md5" == "$new_md5" ] ||
23102                 error "$old_md5 != $new_md5"
23103
23104         return 0
23105 }
23106 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23107
23108 test_272f() {
23109         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23110                 skip "Need MDS version at least 2.12.55"
23111
23112         local dom=$DIR/$tdir/$tfile
23113         mkdir -p $DIR/$tdir
23114         $LFS setstripe -c 2 $dom
23115
23116         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23117                 error "failed to write data into $dom"
23118         local old_md5=$(md5sum $dom)
23119         cancel_lru_locks
23120
23121         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23122                 error "failed migrating to the DOM file"
23123
23124         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23125                 error "MDT stripe wasn't set"
23126
23127         cancel_lru_locks
23128         local new_md5=$(md5sum $dom)
23129         [ "$old_md5" != "$new_md5" ] &&
23130                 error "$old_md5 != $new_md5"
23131
23132         return 0
23133 }
23134 run_test 272f "DoM migration: OST-striped file to DOM file"
23135
23136 test_273a() {
23137         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23138                 skip "Need MDS version at least 2.11.50"
23139
23140         # Layout swap cannot be done if either file has DOM component,
23141         # this will never be supported, migration should be used instead
23142
23143         local dom=$DIR/$tdir/$tfile
23144         mkdir -p $DIR/$tdir
23145
23146         $LFS setstripe -c2 ${dom}_plain
23147         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23148         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23149                 error "can swap layout with DoM component"
23150         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23151                 error "can swap layout with DoM component"
23152
23153         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23154         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23155                 error "can swap layout with DoM component"
23156         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23157                 error "can swap layout with DoM component"
23158         return 0
23159 }
23160 run_test 273a "DoM: layout swapping should fail with DOM"
23161
23162 test_273b() {
23163         mkdir -p $DIR/$tdir
23164         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23165
23166 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23167         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23168
23169         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23170 }
23171 run_test 273b "DoM: race writeback and object destroy"
23172
23173 test_275() {
23174         remote_ost_nodsh && skip "remote OST with nodsh"
23175         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23176                 skip "Need OST version >= 2.10.57"
23177
23178         local file=$DIR/$tfile
23179         local oss
23180
23181         oss=$(comma_list $(osts_nodes))
23182
23183         dd if=/dev/urandom of=$file bs=1M count=2 ||
23184                 error "failed to create a file"
23185         cancel_lru_locks osc
23186
23187         #lock 1
23188         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23189                 error "failed to read a file"
23190
23191 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23192         $LCTL set_param fail_loc=0x8000031f
23193
23194         cancel_lru_locks osc &
23195         sleep 1
23196
23197 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23198         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23199         #IO takes another lock, but matches the PENDING one
23200         #and places it to the IO RPC
23201         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23202                 error "failed to read a file with PENDING lock"
23203 }
23204 run_test 275 "Read on a canceled duplicate lock"
23205
23206 test_276() {
23207         remote_ost_nodsh && skip "remote OST with nodsh"
23208         local pid
23209
23210         do_facet ost1 "(while true; do \
23211                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23212                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23213         pid=$!
23214
23215         for LOOP in $(seq 20); do
23216                 stop ost1
23217                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23218         done
23219         kill -9 $pid
23220         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23221                 rm $TMP/sanity_276_pid"
23222 }
23223 run_test 276 "Race between mount and obd_statfs"
23224
23225 test_277() {
23226         $LCTL set_param ldlm.namespaces.*.lru_size=0
23227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23228         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23229                         grep ^used_mb | awk '{print $2}')
23230         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23231         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23232                 oflag=direct conv=notrunc
23233         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23234                         grep ^used_mb | awk '{print $2}')
23235         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23236 }
23237 run_test 277 "Direct IO shall drop page cache"
23238
23239 test_278() {
23240         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23241         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23242         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23243                 skip "needs the same host for mdt1 mdt2" && return
23244
23245         local pid1
23246         local pid2
23247
23248 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23249         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23250         stop mds2 &
23251         pid2=$!
23252
23253         stop mds1
23254
23255         echo "Starting MDTs"
23256         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23257         wait $pid2
23258 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23259 #will return NULL
23260         do_facet mds2 $LCTL set_param fail_loc=0
23261
23262         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23263         wait_recovery_complete mds2
23264 }
23265 run_test 278 "Race starting MDS between MDTs stop/start"
23266
23267 test_280() {
23268         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23269                 skip "Need MGS version at least 2.13.52"
23270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23271         combined_mgs_mds || skip "needs combined MGS/MDT"
23272
23273         umount_client $MOUNT
23274 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23275         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23276
23277         mount_client $MOUNT &
23278         sleep 1
23279         stop mgs || error "stop mgs failed"
23280         #for a race mgs would crash
23281         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23282         # make sure we unmount client before remounting
23283         wait
23284         umount_client $MOUNT
23285         mount_client $MOUNT || error "mount client failed"
23286 }
23287 run_test 280 "Race between MGS umount and client llog processing"
23288
23289 cleanup_test_300() {
23290         trap 0
23291         umask $SAVE_UMASK
23292 }
23293 test_striped_dir() {
23294         local mdt_index=$1
23295         local stripe_count
23296         local stripe_index
23297
23298         mkdir -p $DIR/$tdir
23299
23300         SAVE_UMASK=$(umask)
23301         trap cleanup_test_300 RETURN EXIT
23302
23303         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23304                                                 $DIR/$tdir/striped_dir ||
23305                 error "set striped dir error"
23306
23307         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23308         [ "$mode" = "755" ] || error "expect 755 got $mode"
23309
23310         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23311                 error "getdirstripe failed"
23312         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23313         if [ "$stripe_count" != "2" ]; then
23314                 error "1:stripe_count is $stripe_count, expect 2"
23315         fi
23316         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23317         if [ "$stripe_count" != "2" ]; then
23318                 error "2:stripe_count is $stripe_count, expect 2"
23319         fi
23320
23321         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23322         if [ "$stripe_index" != "$mdt_index" ]; then
23323                 error "stripe_index is $stripe_index, expect $mdt_index"
23324         fi
23325
23326         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23327                 error "nlink error after create striped dir"
23328
23329         mkdir $DIR/$tdir/striped_dir/a
23330         mkdir $DIR/$tdir/striped_dir/b
23331
23332         stat $DIR/$tdir/striped_dir/a ||
23333                 error "create dir under striped dir failed"
23334         stat $DIR/$tdir/striped_dir/b ||
23335                 error "create dir under striped dir failed"
23336
23337         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23338                 error "nlink error after mkdir"
23339
23340         rmdir $DIR/$tdir/striped_dir/a
23341         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23342                 error "nlink error after rmdir"
23343
23344         rmdir $DIR/$tdir/striped_dir/b
23345         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23346                 error "nlink error after rmdir"
23347
23348         chattr +i $DIR/$tdir/striped_dir
23349         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23350                 error "immutable flags not working under striped dir!"
23351         chattr -i $DIR/$tdir/striped_dir
23352
23353         rmdir $DIR/$tdir/striped_dir ||
23354                 error "rmdir striped dir error"
23355
23356         cleanup_test_300
23357
23358         true
23359 }
23360
23361 test_300a() {
23362         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23363                 skip "skipped for lustre < 2.7.0"
23364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23366
23367         test_striped_dir 0 || error "failed on striped dir on MDT0"
23368         test_striped_dir 1 || error "failed on striped dir on MDT0"
23369 }
23370 run_test 300a "basic striped dir sanity test"
23371
23372 test_300b() {
23373         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23374                 skip "skipped for lustre < 2.7.0"
23375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23377
23378         local i
23379         local mtime1
23380         local mtime2
23381         local mtime3
23382
23383         test_mkdir $DIR/$tdir || error "mkdir fail"
23384         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23385                 error "set striped dir error"
23386         for i in {0..9}; do
23387                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23388                 sleep 1
23389                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23390                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23391                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23392                 sleep 1
23393                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23394                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23395                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23396         done
23397         true
23398 }
23399 run_test 300b "check ctime/mtime for striped dir"
23400
23401 test_300c() {
23402         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23403                 skip "skipped for lustre < 2.7.0"
23404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23406
23407         local file_count
23408
23409         mkdir_on_mdt0 $DIR/$tdir
23410         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23411                 error "set striped dir error"
23412
23413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23414                 error "chown striped dir failed"
23415
23416         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23417                 error "create 5k files failed"
23418
23419         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23420
23421         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23422
23423         rm -rf $DIR/$tdir
23424 }
23425 run_test 300c "chown && check ls under striped directory"
23426
23427 test_300d() {
23428         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23429                 skip "skipped for lustre < 2.7.0"
23430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23432
23433         local stripe_count
23434         local file
23435
23436         mkdir -p $DIR/$tdir
23437         $LFS setstripe -c 2 $DIR/$tdir
23438
23439         #local striped directory
23440         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23441                 error "set striped dir error"
23442         #look at the directories for debug purposes
23443         ls -l $DIR/$tdir
23444         $LFS getdirstripe $DIR/$tdir
23445         ls -l $DIR/$tdir/striped_dir
23446         $LFS getdirstripe $DIR/$tdir/striped_dir
23447         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23448                 error "create 10 files failed"
23449
23450         #remote striped directory
23451         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23452                 error "set striped dir error"
23453         #look at the directories for debug purposes
23454         ls -l $DIR/$tdir
23455         $LFS getdirstripe $DIR/$tdir
23456         ls -l $DIR/$tdir/remote_striped_dir
23457         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23458         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23459                 error "create 10 files failed"
23460
23461         for file in $(find $DIR/$tdir); do
23462                 stripe_count=$($LFS getstripe -c $file)
23463                 [ $stripe_count -eq 2 ] ||
23464                         error "wrong stripe $stripe_count for $file"
23465         done
23466
23467         rm -rf $DIR/$tdir
23468 }
23469 run_test 300d "check default stripe under striped directory"
23470
23471 test_300e() {
23472         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23473                 skip "Need MDS version at least 2.7.55"
23474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23476
23477         local stripe_count
23478         local file
23479
23480         mkdir -p $DIR/$tdir
23481
23482         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23483                 error "set striped dir error"
23484
23485         touch $DIR/$tdir/striped_dir/a
23486         touch $DIR/$tdir/striped_dir/b
23487         touch $DIR/$tdir/striped_dir/c
23488
23489         mkdir $DIR/$tdir/striped_dir/dir_a
23490         mkdir $DIR/$tdir/striped_dir/dir_b
23491         mkdir $DIR/$tdir/striped_dir/dir_c
23492
23493         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23494                 error "set striped adir under striped dir error"
23495
23496         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23497                 error "set striped bdir under striped dir error"
23498
23499         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23500                 error "set striped cdir under striped dir error"
23501
23502         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23503                 error "rename dir under striped dir fails"
23504
23505         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23506                 error "rename dir under different stripes fails"
23507
23508         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23509                 error "rename file under striped dir should succeed"
23510
23511         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23512                 error "rename dir under striped dir should succeed"
23513
23514         rm -rf $DIR/$tdir
23515 }
23516 run_test 300e "check rename under striped directory"
23517
23518 test_300f() {
23519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23521         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23522                 skip "Need MDS version at least 2.7.55"
23523
23524         local stripe_count
23525         local file
23526
23527         rm -rf $DIR/$tdir
23528         mkdir -p $DIR/$tdir
23529
23530         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23531                 error "set striped dir error"
23532
23533         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23534                 error "set striped dir error"
23535
23536         touch $DIR/$tdir/striped_dir/a
23537         mkdir $DIR/$tdir/striped_dir/dir_a
23538         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23539                 error "create striped dir under striped dir fails"
23540
23541         touch $DIR/$tdir/striped_dir1/b
23542         mkdir $DIR/$tdir/striped_dir1/dir_b
23543         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23544                 error "create striped dir under striped dir fails"
23545
23546         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23547                 error "rename dir under different striped dir should fail"
23548
23549         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23550                 error "rename striped dir under diff striped dir should fail"
23551
23552         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23553                 error "rename file under diff striped dirs fails"
23554
23555         rm -rf $DIR/$tdir
23556 }
23557 run_test 300f "check rename cross striped directory"
23558
23559 test_300_check_default_striped_dir()
23560 {
23561         local dirname=$1
23562         local default_count=$2
23563         local default_index=$3
23564         local stripe_count
23565         local stripe_index
23566         local dir_stripe_index
23567         local dir
23568
23569         echo "checking $dirname $default_count $default_index"
23570         $LFS setdirstripe -D -c $default_count -i $default_index \
23571                                 -H all_char $DIR/$tdir/$dirname ||
23572                 error "set default stripe on striped dir error"
23573         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23574         [ $stripe_count -eq $default_count ] ||
23575                 error "expect $default_count get $stripe_count for $dirname"
23576
23577         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23578         [ $stripe_index -eq $default_index ] ||
23579                 error "expect $default_index get $stripe_index for $dirname"
23580
23581         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23582                                                 error "create dirs failed"
23583
23584         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23585         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23586         for dir in $(find $DIR/$tdir/$dirname/*); do
23587                 stripe_count=$($LFS getdirstripe -c $dir)
23588                 (( $stripe_count == $default_count )) ||
23589                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23590                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23591                 error "stripe count $default_count != $stripe_count for $dir"
23592
23593                 stripe_index=$($LFS getdirstripe -i $dir)
23594                 [ $default_index -eq -1 ] ||
23595                         [ $stripe_index -eq $default_index ] ||
23596                         error "$stripe_index != $default_index for $dir"
23597
23598                 #check default stripe
23599                 stripe_count=$($LFS getdirstripe -D -c $dir)
23600                 [ $stripe_count -eq $default_count ] ||
23601                 error "default count $default_count != $stripe_count for $dir"
23602
23603                 stripe_index=$($LFS getdirstripe -D -i $dir)
23604                 [ $stripe_index -eq $default_index ] ||
23605                 error "default index $default_index != $stripe_index for $dir"
23606         done
23607         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23608 }
23609
23610 test_300g() {
23611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23612         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23613                 skip "Need MDS version at least 2.7.55"
23614
23615         local dir
23616         local stripe_count
23617         local stripe_index
23618
23619         mkdir_on_mdt0 $DIR/$tdir
23620         mkdir $DIR/$tdir/normal_dir
23621
23622         #Checking when client cache stripe index
23623         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23624         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23625                 error "create striped_dir failed"
23626
23627         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23628                 error "create dir0 fails"
23629         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23630         [ $stripe_index -eq 0 ] ||
23631                 error "dir0 expect index 0 got $stripe_index"
23632
23633         mkdir $DIR/$tdir/striped_dir/dir1 ||
23634                 error "create dir1 fails"
23635         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23636         [ $stripe_index -eq 1 ] ||
23637                 error "dir1 expect index 1 got $stripe_index"
23638
23639         #check default stripe count/stripe index
23640         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23641         test_300_check_default_striped_dir normal_dir 1 0
23642         test_300_check_default_striped_dir normal_dir -1 1
23643         test_300_check_default_striped_dir normal_dir 2 -1
23644
23645         #delete default stripe information
23646         echo "delete default stripeEA"
23647         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23648                 error "set default stripe on striped dir error"
23649
23650         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23651         for dir in $(find $DIR/$tdir/normal_dir/*); do
23652                 stripe_count=$($LFS getdirstripe -c $dir)
23653                 [ $stripe_count -eq 0 ] ||
23654                         error "expect 1 get $stripe_count for $dir"
23655         done
23656 }
23657 run_test 300g "check default striped directory for normal directory"
23658
23659 test_300h() {
23660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23661         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23662                 skip "Need MDS version at least 2.7.55"
23663
23664         local dir
23665         local stripe_count
23666
23667         mkdir $DIR/$tdir
23668         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23669                 error "set striped dir error"
23670
23671         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23672         test_300_check_default_striped_dir striped_dir 1 0
23673         test_300_check_default_striped_dir striped_dir -1 1
23674         test_300_check_default_striped_dir striped_dir 2 -1
23675
23676         #delete default stripe information
23677         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23678                 error "set default stripe on striped dir error"
23679
23680         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23681         for dir in $(find $DIR/$tdir/striped_dir/*); do
23682                 stripe_count=$($LFS getdirstripe -c $dir)
23683                 [ $stripe_count -eq 0 ] ||
23684                         error "expect 1 get $stripe_count for $dir"
23685         done
23686 }
23687 run_test 300h "check default striped directory for striped directory"
23688
23689 test_300i() {
23690         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23691         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23692         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23693                 skip "Need MDS version at least 2.7.55"
23694
23695         local stripe_count
23696         local file
23697
23698         mkdir $DIR/$tdir
23699
23700         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23701                 error "set striped dir error"
23702
23703         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23704                 error "create files under striped dir failed"
23705
23706         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23707                 error "set striped hashdir error"
23708
23709         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23710                 error "create dir0 under hash dir failed"
23711         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23712                 error "create dir1 under hash dir failed"
23713         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23714                 error "create dir2 under hash dir failed"
23715
23716         # unfortunately, we need to umount to clear dir layout cache for now
23717         # once we fully implement dir layout, we can drop this
23718         umount_client $MOUNT || error "umount failed"
23719         mount_client $MOUNT || error "mount failed"
23720
23721         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23722         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23723         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23724
23725         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23726                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23727                         error "create crush2 dir $tdir/hashdir/d3 failed"
23728                 $LFS find -H crush2 $DIR/$tdir/hashdir
23729                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23730                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23731
23732                 # mkdir with an invalid hash type (hash=fail_val) from client
23733                 # should be replaced on MDS with a valid (default) hash type
23734                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23735                 $LCTL set_param fail_loc=0x1901 fail_val=99
23736                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23737
23738                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23739                 local expect=$(do_facet mds1 \
23740                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23741                 [[ $hash == $expect ]] ||
23742                         error "d99 hash '$hash' != expected hash '$expect'"
23743         fi
23744
23745         #set the stripe to be unknown hash type on read
23746         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23747         $LCTL set_param fail_loc=0x1901 fail_val=99
23748         for ((i = 0; i < 10; i++)); do
23749                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23750                         error "stat f-$i failed"
23751                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23752         done
23753
23754         touch $DIR/$tdir/striped_dir/f0 &&
23755                 error "create under striped dir with unknown hash should fail"
23756
23757         $LCTL set_param fail_loc=0
23758
23759         umount_client $MOUNT || error "umount failed"
23760         mount_client $MOUNT || error "mount failed"
23761
23762         return 0
23763 }
23764 run_test 300i "client handle unknown hash type striped directory"
23765
23766 test_300j() {
23767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23769         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23770                 skip "Need MDS version at least 2.7.55"
23771
23772         local stripe_count
23773         local file
23774
23775         mkdir $DIR/$tdir
23776
23777         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23778         $LCTL set_param fail_loc=0x1702
23779         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23780                 error "set striped dir error"
23781
23782         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23783                 error "create files under striped dir failed"
23784
23785         $LCTL set_param fail_loc=0
23786
23787         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23788
23789         return 0
23790 }
23791 run_test 300j "test large update record"
23792
23793 test_300k() {
23794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23797                 skip "Need MDS version at least 2.7.55"
23798
23799         # this test needs a huge transaction
23800         local kb
23801         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23802              osd*.$FSNAME-MDT0000.kbytestotal")
23803         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23804
23805         local stripe_count
23806         local file
23807
23808         mkdir $DIR/$tdir
23809
23810         #define OBD_FAIL_LARGE_STRIPE   0x1703
23811         $LCTL set_param fail_loc=0x1703
23812         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23813                 error "set striped dir error"
23814         $LCTL set_param fail_loc=0
23815
23816         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23817                 error "getstripeddir fails"
23818         rm -rf $DIR/$tdir/striped_dir ||
23819                 error "unlink striped dir fails"
23820
23821         return 0
23822 }
23823 run_test 300k "test large striped directory"
23824
23825 test_300l() {
23826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23828         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23829                 skip "Need MDS version at least 2.7.55"
23830
23831         local stripe_index
23832
23833         test_mkdir -p $DIR/$tdir/striped_dir
23834         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23835                         error "chown $RUNAS_ID failed"
23836         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23837                 error "set default striped dir failed"
23838
23839         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23840         $LCTL set_param fail_loc=0x80000158
23841         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23842
23843         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23844         [ $stripe_index -eq 1 ] ||
23845                 error "expect 1 get $stripe_index for $dir"
23846 }
23847 run_test 300l "non-root user to create dir under striped dir with stale layout"
23848
23849 test_300m() {
23850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23851         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23852         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23853                 skip "Need MDS version at least 2.7.55"
23854
23855         mkdir -p $DIR/$tdir/striped_dir
23856         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23857                 error "set default stripes dir error"
23858
23859         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23860
23861         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23862         [ $stripe_count -eq 0 ] ||
23863                         error "expect 0 get $stripe_count for a"
23864
23865         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23866                 error "set default stripes dir error"
23867
23868         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23869
23870         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23871         [ $stripe_count -eq 0 ] ||
23872                         error "expect 0 get $stripe_count for b"
23873
23874         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23875                 error "set default stripes dir error"
23876
23877         mkdir $DIR/$tdir/striped_dir/c &&
23878                 error "default stripe_index is invalid, mkdir c should fails"
23879
23880         rm -rf $DIR/$tdir || error "rmdir fails"
23881 }
23882 run_test 300m "setstriped directory on single MDT FS"
23883
23884 cleanup_300n() {
23885         local list=$(comma_list $(mdts_nodes))
23886
23887         trap 0
23888         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23889 }
23890
23891 test_300n() {
23892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23894         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23895                 skip "Need MDS version at least 2.7.55"
23896         remote_mds_nodsh && skip "remote MDS with nodsh"
23897
23898         local stripe_index
23899         local list=$(comma_list $(mdts_nodes))
23900
23901         trap cleanup_300n RETURN EXIT
23902         mkdir -p $DIR/$tdir
23903         chmod 777 $DIR/$tdir
23904         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23905                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23906                 error "create striped dir succeeds with gid=0"
23907
23908         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23909         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23910                 error "create striped dir fails with gid=-1"
23911
23912         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23913         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23914                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23915                 error "set default striped dir succeeds with gid=0"
23916
23917
23918         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23919         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23920                 error "set default striped dir fails with gid=-1"
23921
23922
23923         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23924         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23925                                         error "create test_dir fails"
23926         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23927                                         error "create test_dir1 fails"
23928         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23929                                         error "create test_dir2 fails"
23930         cleanup_300n
23931 }
23932 run_test 300n "non-root user to create dir under striped dir with default EA"
23933
23934 test_300o() {
23935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23937         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23938                 skip "Need MDS version at least 2.7.55"
23939
23940         local numfree1
23941         local numfree2
23942
23943         mkdir -p $DIR/$tdir
23944
23945         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23946         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23947         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23948                 skip "not enough free inodes $numfree1 $numfree2"
23949         fi
23950
23951         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23952         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23953         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23954                 skip "not enough free space $numfree1 $numfree2"
23955         fi
23956
23957         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23958                 error "setdirstripe fails"
23959
23960         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23961                 error "create dirs fails"
23962
23963         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23964         ls $DIR/$tdir/striped_dir > /dev/null ||
23965                 error "ls striped dir fails"
23966         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23967                 error "unlink big striped dir fails"
23968 }
23969 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23970
23971 test_300p() {
23972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23974         remote_mds_nodsh && skip "remote MDS with nodsh"
23975
23976         mkdir_on_mdt0 $DIR/$tdir
23977
23978         #define OBD_FAIL_OUT_ENOSPC     0x1704
23979         do_facet mds2 lctl set_param fail_loc=0x80001704
23980         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23981                  && error "create striped directory should fail"
23982
23983         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23984
23985         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23986         true
23987 }
23988 run_test 300p "create striped directory without space"
23989
23990 test_300q() {
23991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23993
23994         local fd=$(free_fd)
23995         local cmd="exec $fd<$tdir"
23996         cd $DIR
23997         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23998         eval $cmd
23999         cmd="exec $fd<&-"
24000         trap "eval $cmd" EXIT
24001         cd $tdir || error "cd $tdir fails"
24002         rmdir  ../$tdir || error "rmdir $tdir fails"
24003         mkdir local_dir && error "create dir succeeds"
24004         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24005         eval $cmd
24006         return 0
24007 }
24008 run_test 300q "create remote directory under orphan directory"
24009
24010 test_300r() {
24011         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24012                 skip "Need MDS version at least 2.7.55" && return
24013         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24014
24015         mkdir $DIR/$tdir
24016
24017         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24018                 error "set striped dir error"
24019
24020         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24021                 error "getstripeddir fails"
24022
24023         local stripe_count
24024         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24025                       awk '/lmv_stripe_count:/ { print $2 }')
24026
24027         [ $MDSCOUNT -ne $stripe_count ] &&
24028                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24029
24030         rm -rf $DIR/$tdir/striped_dir ||
24031                 error "unlink striped dir fails"
24032 }
24033 run_test 300r "test -1 striped directory"
24034
24035 test_300s_helper() {
24036         local count=$1
24037
24038         local stripe_dir=$DIR/$tdir/striped_dir.$count
24039
24040         $LFS mkdir -c $count $stripe_dir ||
24041                 error "lfs mkdir -c error"
24042
24043         $LFS getdirstripe $stripe_dir ||
24044                 error "lfs getdirstripe fails"
24045
24046         local stripe_count
24047         stripe_count=$($LFS getdirstripe $stripe_dir |
24048                       awk '/lmv_stripe_count:/ { print $2 }')
24049
24050         [ $count -ne $stripe_count ] &&
24051                 error_noexit "bad stripe count $stripe_count expected $count"
24052
24053         local dupe_stripes
24054         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24055                 awk '/0x/ {count[$1] += 1}; END {
24056                         for (idx in count) {
24057                                 if (count[idx]>1) {
24058                                         print "index " idx " count " count[idx]
24059                                 }
24060                         }
24061                 }')
24062
24063         if [[ -n "$dupe_stripes" ]] ; then
24064                 lfs getdirstripe $stripe_dir
24065                 error_noexit "Dupe MDT above: $dupe_stripes "
24066         fi
24067
24068         rm -rf $stripe_dir ||
24069                 error_noexit "unlink $stripe_dir fails"
24070 }
24071
24072 test_300s() {
24073         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24074                 skip "Need MDS version at least 2.7.55" && return
24075         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24076
24077         mkdir $DIR/$tdir
24078         for count in $(seq 2 $MDSCOUNT); do
24079                 test_300s_helper $count
24080         done
24081 }
24082 run_test 300s "test lfs mkdir -c without -i"
24083
24084 test_300t() {
24085         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24086                 skip "need MDS 2.14.55 or later"
24087         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24088
24089         local testdir="$DIR/$tdir/striped_dir"
24090         local dir1=$testdir/dir1
24091         local dir2=$testdir/dir2
24092
24093         mkdir -p $testdir
24094
24095         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24096                 error "failed to set default stripe count for $testdir"
24097
24098         mkdir $dir1
24099         local stripe_count=$($LFS getdirstripe -c $dir1)
24100
24101         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24102
24103         local max_count=$((MDSCOUNT - 1))
24104         local mdts=$(comma_list $(mdts_nodes))
24105
24106         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24107         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24108
24109         mkdir $dir2
24110         stripe_count=$($LFS getdirstripe -c $dir2)
24111
24112         (( $stripe_count == $max_count )) || error "wrong stripe count"
24113 }
24114 run_test 300t "test max_mdt_stripecount"
24115
24116 prepare_remote_file() {
24117         mkdir $DIR/$tdir/src_dir ||
24118                 error "create remote source failed"
24119
24120         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24121                  error "cp to remote source failed"
24122         touch $DIR/$tdir/src_dir/a
24123
24124         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24125                 error "create remote target dir failed"
24126
24127         touch $DIR/$tdir/tgt_dir/b
24128
24129         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24130                 error "rename dir cross MDT failed!"
24131
24132         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24133                 error "src_child still exists after rename"
24134
24135         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24136                 error "missing file(a) after rename"
24137
24138         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24139                 error "diff after rename"
24140 }
24141
24142 test_310a() {
24143         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24145
24146         local remote_file=$DIR/$tdir/tgt_dir/b
24147
24148         mkdir -p $DIR/$tdir
24149
24150         prepare_remote_file || error "prepare remote file failed"
24151
24152         #open-unlink file
24153         $OPENUNLINK $remote_file $remote_file ||
24154                 error "openunlink $remote_file failed"
24155         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24156 }
24157 run_test 310a "open unlink remote file"
24158
24159 test_310b() {
24160         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24162
24163         local remote_file=$DIR/$tdir/tgt_dir/b
24164
24165         mkdir -p $DIR/$tdir
24166
24167         prepare_remote_file || error "prepare remote file failed"
24168
24169         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24170         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24171         $CHECKSTAT -t file $remote_file || error "check file failed"
24172 }
24173 run_test 310b "unlink remote file with multiple links while open"
24174
24175 test_310c() {
24176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24177         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24178
24179         local remote_file=$DIR/$tdir/tgt_dir/b
24180
24181         mkdir -p $DIR/$tdir
24182
24183         prepare_remote_file || error "prepare remote file failed"
24184
24185         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24186         multiop_bg_pause $remote_file O_uc ||
24187                         error "mulitop failed for remote file"
24188         MULTIPID=$!
24189         $MULTIOP $DIR/$tfile Ouc
24190         kill -USR1 $MULTIPID
24191         wait $MULTIPID
24192 }
24193 run_test 310c "open-unlink remote file with multiple links"
24194
24195 #LU-4825
24196 test_311() {
24197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24198         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24199         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24200                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24201         remote_mds_nodsh && skip "remote MDS with nodsh"
24202
24203         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24204         local mdts=$(comma_list $(mdts_nodes))
24205
24206         mkdir -p $DIR/$tdir
24207         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24208         createmany -o $DIR/$tdir/$tfile. 1000
24209
24210         # statfs data is not real time, let's just calculate it
24211         old_iused=$((old_iused + 1000))
24212
24213         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24214                         osp.*OST0000*MDT0000.create_count")
24215         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24216                                 osp.*OST0000*MDT0000.max_create_count")
24217         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24218
24219         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24220         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24221         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24222
24223         unlinkmany $DIR/$tdir/$tfile. 1000
24224
24225         do_nodes $mdts "$LCTL set_param -n \
24226                         osp.*OST0000*.max_create_count=$max_count"
24227         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24228                 do_nodes $mdts "$LCTL set_param -n \
24229                                 osp.*OST0000*.create_count=$count"
24230         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24231                         grep "=0" && error "create_count is zero"
24232
24233         local new_iused
24234         for i in $(seq 120); do
24235                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24236                 # system may be too busy to destroy all objs in time, use
24237                 # a somewhat small value to not fail autotest
24238                 [ $((old_iused - new_iused)) -gt 400 ] && break
24239                 sleep 1
24240         done
24241
24242         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24243         [ $((old_iused - new_iused)) -gt 400 ] ||
24244                 error "objs not destroyed after unlink"
24245 }
24246 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24247
24248 zfs_oid_to_objid()
24249 {
24250         local ost=$1
24251         local objid=$2
24252
24253         local vdevdir=$(dirname $(facet_vdevice $ost))
24254         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24255         local zfs_zapid=$(do_facet $ost $cmd |
24256                           grep -w "/O/0/d$((objid%32))" -C 5 |
24257                           awk '/Object/{getline; print $1}')
24258         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24259                           awk "/$objid = /"'{printf $3}')
24260
24261         echo $zfs_objid
24262 }
24263
24264 zfs_object_blksz() {
24265         local ost=$1
24266         local objid=$2
24267
24268         local vdevdir=$(dirname $(facet_vdevice $ost))
24269         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24270         local blksz=$(do_facet $ost $cmd $objid |
24271                       awk '/dblk/{getline; printf $4}')
24272
24273         case "${blksz: -1}" in
24274                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24275                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24276                 *) ;;
24277         esac
24278
24279         echo $blksz
24280 }
24281
24282 test_312() { # LU-4856
24283         remote_ost_nodsh && skip "remote OST with nodsh"
24284         [ "$ost1_FSTYPE" = "zfs" ] ||
24285                 skip_env "the test only applies to zfs"
24286
24287         local max_blksz=$(do_facet ost1 \
24288                           $ZFS get -p recordsize $(facet_device ost1) |
24289                           awk '!/VALUE/{print $3}')
24290
24291         # to make life a little bit easier
24292         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24293         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24294
24295         local tf=$DIR/$tdir/$tfile
24296         touch $tf
24297         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24298
24299         # Get ZFS object id
24300         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24301         # block size change by sequential overwrite
24302         local bs
24303
24304         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24305                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24306
24307                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24308                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24309         done
24310         rm -f $tf
24311
24312         # block size change by sequential append write
24313         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24314         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24315         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24316         local count
24317
24318         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24319                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24320                         oflag=sync conv=notrunc
24321
24322                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24323                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24324                         error "blksz error, actual $blksz, " \
24325                                 "expected: 2 * $count * $PAGE_SIZE"
24326         done
24327         rm -f $tf
24328
24329         # random write
24330         touch $tf
24331         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24332         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24333
24334         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24335         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24336         [ $blksz -eq $PAGE_SIZE ] ||
24337                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24338
24339         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24340         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24341         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24342
24343         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24344         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24345         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24346 }
24347 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24348
24349 test_313() {
24350         remote_ost_nodsh && skip "remote OST with nodsh"
24351
24352         local file=$DIR/$tfile
24353
24354         rm -f $file
24355         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24356
24357         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24358         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24359         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24360                 error "write should failed"
24361         do_facet ost1 "$LCTL set_param fail_loc=0"
24362         rm -f $file
24363 }
24364 run_test 313 "io should fail after last_rcvd update fail"
24365
24366 test_314() {
24367         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24368
24369         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24370         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24371         rm -f $DIR/$tfile
24372         wait_delete_completed
24373         do_facet ost1 "$LCTL set_param fail_loc=0"
24374 }
24375 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24376
24377 test_315() { # LU-618
24378         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24379
24380         local file=$DIR/$tfile
24381         rm -f $file
24382
24383         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24384                 error "multiop file write failed"
24385         $MULTIOP $file oO_RDONLY:r4063232_c &
24386         PID=$!
24387
24388         sleep 2
24389
24390         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24391         kill -USR1 $PID
24392
24393         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24394         rm -f $file
24395 }
24396 run_test 315 "read should be accounted"
24397
24398 test_316() {
24399         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24400         large_xattr_enabled || skip "ea_inode feature disabled"
24401
24402         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24403         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24404         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24405         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24406
24407         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24408 }
24409 run_test 316 "lfs migrate of file with large_xattr enabled"
24410
24411 test_317() {
24412         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24413                 skip "Need MDS version at least 2.11.53"
24414         if [ "$ost1_FSTYPE" == "zfs" ]; then
24415                 skip "LU-10370: no implementation for ZFS"
24416         fi
24417
24418         local trunc_sz
24419         local grant_blk_size
24420
24421         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24422                         awk '/grant_block_size:/ { print $2; exit; }')
24423         #
24424         # Create File of size 5M. Truncate it to below size's and verify
24425         # blocks count.
24426         #
24427         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24428                 error "Create file $DIR/$tfile failed"
24429         stack_trap "rm -f $DIR/$tfile" EXIT
24430
24431         for trunc_sz in 2097152 4097 4000 509 0; do
24432                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24433                         error "truncate $tfile to $trunc_sz failed"
24434                 local sz=$(stat --format=%s $DIR/$tfile)
24435                 local blk=$(stat --format=%b $DIR/$tfile)
24436                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24437                                      grant_blk_size) * 8))
24438
24439                 if [[ $blk -ne $trunc_blk ]]; then
24440                         $(which stat) $DIR/$tfile
24441                         error "Expected Block $trunc_blk got $blk for $tfile"
24442                 fi
24443
24444                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24445                         error "Expected Size $trunc_sz got $sz for $tfile"
24446         done
24447
24448         #
24449         # sparse file test
24450         # Create file with a hole and write actual 65536 bytes which aligned
24451         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24452         #
24453         local bs=65536
24454         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24455                 error "Create file : $DIR/$tfile"
24456
24457         #
24458         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24459         # blocks. The block count must drop to 8.
24460         #
24461         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24462                 ((bs - grant_blk_size) + 1)))
24463         $TRUNCATE $DIR/$tfile $trunc_sz ||
24464                 error "truncate $tfile to $trunc_sz failed"
24465
24466         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24467         sz=$(stat --format=%s $DIR/$tfile)
24468         blk=$(stat --format=%b $DIR/$tfile)
24469
24470         if [[ $blk -ne $trunc_bsz ]]; then
24471                 $(which stat) $DIR/$tfile
24472                 error "Expected Block $trunc_bsz got $blk for $tfile"
24473         fi
24474
24475         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24476                 error "Expected Size $trunc_sz got $sz for $tfile"
24477 }
24478 run_test 317 "Verify blocks get correctly update after truncate"
24479
24480 test_318() {
24481         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24482         local old_max_active=$($LCTL get_param -n \
24483                             ${llite_name}.max_read_ahead_async_active \
24484                             2>/dev/null)
24485
24486         $LCTL set_param llite.*.max_read_ahead_async_active=256
24487         local max_active=$($LCTL get_param -n \
24488                            ${llite_name}.max_read_ahead_async_active \
24489                            2>/dev/null)
24490         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24491
24492         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24493                 error "set max_read_ahead_async_active should succeed"
24494
24495         $LCTL set_param llite.*.max_read_ahead_async_active=512
24496         max_active=$($LCTL get_param -n \
24497                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24498         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24499
24500         # restore @max_active
24501         [ $old_max_active -ne 0 ] && $LCTL set_param \
24502                 llite.*.max_read_ahead_async_active=$old_max_active
24503
24504         local old_threshold=$($LCTL get_param -n \
24505                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24506         local max_per_file_mb=$($LCTL get_param -n \
24507                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24508
24509         local invalid=$(($max_per_file_mb + 1))
24510         $LCTL set_param \
24511                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24512                         && error "set $invalid should fail"
24513
24514         local valid=$(($invalid - 1))
24515         $LCTL set_param \
24516                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24517                         error "set $valid should succeed"
24518         local threshold=$($LCTL get_param -n \
24519                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24520         [ $threshold -eq $valid ] || error \
24521                 "expect threshold $valid got $threshold"
24522         $LCTL set_param \
24523                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24524 }
24525 run_test 318 "Verify async readahead tunables"
24526
24527 test_319() {
24528         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24529
24530         local before=$(date +%s)
24531         local evict
24532         local mdir=$DIR/$tdir
24533         local file=$mdir/xxx
24534
24535         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24536         touch $file
24537
24538 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24539         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24540         $LFS migrate -m1 $mdir &
24541
24542         sleep 1
24543         dd if=$file of=/dev/null
24544         wait
24545         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24546           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24547
24548         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24549 }
24550 run_test 319 "lost lease lock on migrate error"
24551
24552 test_398a() { # LU-4198
24553         local ost1_imp=$(get_osc_import_name client ost1)
24554         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24555                          cut -d'.' -f2)
24556
24557         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24558         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24559
24560         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24561         # request a new lock on client
24562         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24563
24564         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24565         #local lock_count=$($LCTL get_param -n \
24566         #                  ldlm.namespaces.$imp_name.lru_size)
24567         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24568
24569         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24570
24571         # no lock cached, should use lockless DIO and not enqueue new lock
24572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24573                 conv=notrunc ||
24574                 error "dio write failed"
24575         lock_count=$($LCTL get_param -n \
24576                      ldlm.namespaces.$imp_name.lru_size)
24577         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24578
24579         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24580
24581         # no lock cached, should use locked DIO append
24582         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24583                 conv=notrunc || error "DIO append failed"
24584         lock_count=$($LCTL get_param -n \
24585                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24586         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24587 }
24588 run_test 398a "direct IO should cancel lock otherwise lockless"
24589
24590 test_398b() { # LU-4198
24591         which fio || skip_env "no fio installed"
24592         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24593
24594         local size=48
24595         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24596
24597         local njobs=4
24598         # Single page, multiple pages, stripe size, 4*stripe size
24599         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24600                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24601                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24602                         --numjobs=$njobs --fallocate=none \
24603                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24604                         --filename=$DIR/$tfile &
24605                 bg_pid=$!
24606
24607                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24608                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24609                         --numjobs=$njobs --fallocate=none \
24610                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24611                         --filename=$DIR/$tfile || true
24612                 wait $bg_pid
24613         done
24614
24615         evict=$(do_facet client $LCTL get_param \
24616                 osc.$FSNAME-OST*-osc-*/state |
24617             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24618
24619         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24620                 (do_facet client $LCTL get_param \
24621                         osc.$FSNAME-OST*-osc-*/state;
24622                     error "eviction happened: $evict before:$before")
24623
24624         rm -f $DIR/$tfile
24625 }
24626 run_test 398b "DIO and buffer IO race"
24627
24628 test_398c() { # LU-4198
24629         local ost1_imp=$(get_osc_import_name client ost1)
24630         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24631                          cut -d'.' -f2)
24632
24633         which fio || skip_env "no fio installed"
24634
24635         saved_debug=$($LCTL get_param -n debug)
24636         $LCTL set_param debug=0
24637
24638         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24639         ((size /= 1024)) # by megabytes
24640         ((size /= 2)) # write half of the OST at most
24641         [ $size -gt 40 ] && size=40 #reduce test time anyway
24642
24643         $LFS setstripe -c 1 $DIR/$tfile
24644
24645         # it seems like ldiskfs reserves more space than necessary if the
24646         # writing blocks are not mapped, so it extends the file firstly
24647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24648         cancel_lru_locks osc
24649
24650         # clear and verify rpc_stats later
24651         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24652
24653         local njobs=4
24654         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24655         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24656                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24657                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24658                 --filename=$DIR/$tfile
24659         [ $? -eq 0 ] || error "fio write error"
24660
24661         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24662                 error "Locks were requested while doing AIO"
24663
24664         # get the percentage of 1-page I/O
24665         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24666                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24667                 awk '{print $7}')
24668         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24669
24670         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24671         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24672                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24673                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24674                 --filename=$DIR/$tfile
24675         [ $? -eq 0 ] || error "fio mixed read write error"
24676
24677         echo "AIO with large block size ${size}M"
24678         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24679                 --numjobs=1 --fallocate=none --ioengine=libaio \
24680                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24681                 --filename=$DIR/$tfile
24682         [ $? -eq 0 ] || error "fio large block size failed"
24683
24684         rm -f $DIR/$tfile
24685         $LCTL set_param debug="$saved_debug"
24686 }
24687 run_test 398c "run fio to test AIO"
24688
24689 test_398d() { #  LU-13846
24690         which aiocp || skip_env "no aiocp installed"
24691         local aio_file=$DIR/$tfile.aio
24692
24693         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24694
24695         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24696         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24697         stack_trap "rm -f $DIR/$tfile $aio_file"
24698
24699         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24700
24701         # make sure we don't crash and fail properly
24702         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24703                 error "aio not aligned with PAGE SIZE should fail"
24704
24705         rm -f $DIR/$tfile $aio_file
24706 }
24707 run_test 398d "run aiocp to verify block size > stripe size"
24708
24709 test_398e() {
24710         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24711         touch $DIR/$tfile.new
24712         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24713 }
24714 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24715
24716 test_398f() { #  LU-14687
24717         which aiocp || skip_env "no aiocp installed"
24718         local aio_file=$DIR/$tfile.aio
24719
24720         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24721
24722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24723         stack_trap "rm -f $DIR/$tfile $aio_file"
24724
24725         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24726         $LCTL set_param fail_loc=0x1418
24727         # make sure we don't crash and fail properly
24728         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24729                 error "aio with page allocation failure succeeded"
24730         $LCTL set_param fail_loc=0
24731         diff $DIR/$tfile $aio_file
24732         [[ $? != 0 ]] || error "no diff after failed aiocp"
24733 }
24734 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24735
24736 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24737 # stripe and i/o size must be > stripe size
24738 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24739 # single RPC in flight.  This test shows async DIO submission is working by
24740 # showing multiple RPCs in flight.
24741 test_398g() { #  LU-13798
24742         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24743
24744         # We need to do some i/o first to acquire enough grant to put our RPCs
24745         # in flight; otherwise a new connection may not have enough grant
24746         # available
24747         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24748                 error "parallel dio failed"
24749         stack_trap "rm -f $DIR/$tfile"
24750
24751         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24752         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24753         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24754         stack_trap "$LCTL set_param -n $pages_per_rpc"
24755
24756         # Recreate file so it's empty
24757         rm -f $DIR/$tfile
24758         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24759         #Pause rpc completion to guarantee we see multiple rpcs in flight
24760         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24761         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24762         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24763
24764         # Clear rpc stats
24765         $LCTL set_param osc.*.rpc_stats=c
24766
24767         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24768                 error "parallel dio failed"
24769         stack_trap "rm -f $DIR/$tfile"
24770
24771         $LCTL get_param osc.*-OST0000-*.rpc_stats
24772         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24773                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24774                 grep "8:" | awk '{print $8}')
24775         # We look at the "8 rpcs in flight" field, and verify A) it is present
24776         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24777         # as expected for an 8M DIO to a file with 1M stripes.
24778         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24779
24780         # Verify turning off parallel dio works as expected
24781         # Clear rpc stats
24782         $LCTL set_param osc.*.rpc_stats=c
24783         $LCTL set_param llite.*.parallel_dio=0
24784         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24785
24786         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24787                 error "dio with parallel dio disabled failed"
24788
24789         # Ideally, we would see only one RPC in flight here, but there is an
24790         # unavoidable race between i/o completion and RPC in flight counting,
24791         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24792         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24793         # So instead we just verify it's always < 8.
24794         $LCTL get_param osc.*-OST0000-*.rpc_stats
24795         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24796                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24797                 grep '^$' -B1 | grep . | awk '{print $1}')
24798         [ $ret != "8:" ] ||
24799                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24800 }
24801 run_test 398g "verify parallel dio async RPC submission"
24802
24803 test_398h() { #  LU-13798
24804         local dio_file=$DIR/$tfile.dio
24805
24806         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24807
24808         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24809         stack_trap "rm -f $DIR/$tfile $dio_file"
24810
24811         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24812                 error "parallel dio failed"
24813         diff $DIR/$tfile $dio_file
24814         [[ $? == 0 ]] || error "file diff after aiocp"
24815 }
24816 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24817
24818 test_398i() { #  LU-13798
24819         local dio_file=$DIR/$tfile.dio
24820
24821         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24822
24823         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24824         stack_trap "rm -f $DIR/$tfile $dio_file"
24825
24826         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24827         $LCTL set_param fail_loc=0x1418
24828         # make sure we don't crash and fail properly
24829         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24830                 error "parallel dio page allocation failure succeeded"
24831         diff $DIR/$tfile $dio_file
24832         [[ $? != 0 ]] || error "no diff after failed aiocp"
24833 }
24834 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24835
24836 test_398j() { #  LU-13798
24837         # Stripe size > RPC size but less than i/o size tests split across
24838         # stripes and RPCs for individual i/o op
24839         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24840
24841         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24842         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24843         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24844         stack_trap "$LCTL set_param -n $pages_per_rpc"
24845
24846         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24847                 error "parallel dio write failed"
24848         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24849
24850         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24851                 error "parallel dio read failed"
24852         diff $DIR/$tfile $DIR/$tfile.2
24853         [[ $? == 0 ]] || error "file diff after parallel dio read"
24854 }
24855 run_test 398j "test parallel dio where stripe size > rpc_size"
24856
24857 test_398k() { #  LU-13798
24858         wait_delete_completed
24859         wait_mds_ost_sync
24860
24861         # 4 stripe file; we will cause out of space on OST0
24862         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24863
24864         # Fill OST0 (if it's not too large)
24865         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24866                    head -n1)
24867         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24868                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24869         fi
24870         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24871         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24872                 error "dd should fill OST0"
24873         stack_trap "rm -f $DIR/$tfile.1"
24874
24875         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24876         err=$?
24877
24878         ls -la $DIR/$tfile
24879         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24880                 error "file is not 0 bytes in size"
24881
24882         # dd above should not succeed, but don't error until here so we can
24883         # get debug info above
24884         [[ $err != 0 ]] ||
24885                 error "parallel dio write with enospc succeeded"
24886         stack_trap "rm -f $DIR/$tfile"
24887 }
24888 run_test 398k "test enospc on first stripe"
24889
24890 test_398l() { #  LU-13798
24891         wait_delete_completed
24892         wait_mds_ost_sync
24893
24894         # 4 stripe file; we will cause out of space on OST0
24895         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24896         # happens on the second i/o chunk we issue
24897         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24898
24899         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24900         stack_trap "rm -f $DIR/$tfile"
24901
24902         # Fill OST0 (if it's not too large)
24903         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24904                    head -n1)
24905         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24906                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24907         fi
24908         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24909         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24910                 error "dd should fill OST0"
24911         stack_trap "rm -f $DIR/$tfile.1"
24912
24913         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24914         err=$?
24915         stack_trap "rm -f $DIR/$tfile.2"
24916
24917         # Check that short write completed as expected
24918         ls -la $DIR/$tfile.2
24919         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24920                 error "file is not 1M in size"
24921
24922         # dd above should not succeed, but don't error until here so we can
24923         # get debug info above
24924         [[ $err != 0 ]] ||
24925                 error "parallel dio write with enospc succeeded"
24926
24927         # Truncate source file to same length as output file and diff them
24928         $TRUNCATE $DIR/$tfile 1048576
24929         diff $DIR/$tfile $DIR/$tfile.2
24930         [[ $? == 0 ]] || error "data incorrect after short write"
24931 }
24932 run_test 398l "test enospc on intermediate stripe/RPC"
24933
24934 test_398m() { #  LU-13798
24935         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24936
24937         # Set up failure on OST0, the first stripe:
24938         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24939         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24940         # So this fail_val specifies OST0
24941         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24942         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24943
24944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24945                 error "parallel dio write with failure on first stripe succeeded"
24946         stack_trap "rm -f $DIR/$tfile"
24947         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24948
24949         # Place data in file for read
24950         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24951                 error "parallel dio write failed"
24952
24953         # Fail read on OST0, first stripe
24954         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24955         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24956         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24957                 error "parallel dio read with error on first stripe succeeded"
24958         rm -f $DIR/$tfile.2
24959         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24960
24961         # Switch to testing on OST1, second stripe
24962         # Clear file contents, maintain striping
24963         echo > $DIR/$tfile
24964         # Set up failure on OST1, second stripe:
24965         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24966         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24967
24968         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24969                 error "parallel dio write with failure on first stripe succeeded"
24970         stack_trap "rm -f $DIR/$tfile"
24971         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24972
24973         # Place data in file for read
24974         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24975                 error "parallel dio write failed"
24976
24977         # Fail read on OST1, second stripe
24978         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24979         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24980         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24981                 error "parallel dio read with error on first stripe succeeded"
24982         rm -f $DIR/$tfile.2
24983         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24984 }
24985 run_test 398m "test RPC failures with parallel dio"
24986
24987 # Parallel submission of DIO should not cause problems for append, but it's
24988 # important to verify.
24989 test_398n() { #  LU-13798
24990         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24991
24992         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24993                 error "dd to create source file failed"
24994         stack_trap "rm -f $DIR/$tfile"
24995
24996         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24997                 error "parallel dio write with failure on second stripe succeeded"
24998         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24999         diff $DIR/$tfile $DIR/$tfile.1
25000         [[ $? == 0 ]] || error "data incorrect after append"
25001
25002 }
25003 run_test 398n "test append with parallel DIO"
25004
25005 test_fake_rw() {
25006         local read_write=$1
25007         if [ "$read_write" = "write" ]; then
25008                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25009         elif [ "$read_write" = "read" ]; then
25010                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25011         else
25012                 error "argument error"
25013         fi
25014
25015         # turn off debug for performance testing
25016         local saved_debug=$($LCTL get_param -n debug)
25017         $LCTL set_param debug=0
25018
25019         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25020
25021         # get ost1 size - $FSNAME-OST0000
25022         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25023         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25024         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25025
25026         if [ "$read_write" = "read" ]; then
25027                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25028         fi
25029
25030         local start_time=$(date +%s.%N)
25031         $dd_cmd bs=1M count=$blocks oflag=sync ||
25032                 error "real dd $read_write error"
25033         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25034
25035         if [ "$read_write" = "write" ]; then
25036                 rm -f $DIR/$tfile
25037         fi
25038
25039         # define OBD_FAIL_OST_FAKE_RW           0x238
25040         do_facet ost1 $LCTL set_param fail_loc=0x238
25041
25042         local start_time=$(date +%s.%N)
25043         $dd_cmd bs=1M count=$blocks oflag=sync ||
25044                 error "fake dd $read_write error"
25045         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25046
25047         if [ "$read_write" = "write" ]; then
25048                 # verify file size
25049                 cancel_lru_locks osc
25050                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25051                         error "$tfile size not $blocks MB"
25052         fi
25053         do_facet ost1 $LCTL set_param fail_loc=0
25054
25055         echo "fake $read_write $duration_fake vs. normal $read_write" \
25056                 "$duration in seconds"
25057         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25058                 error_not_in_vm "fake write is slower"
25059
25060         $LCTL set_param -n debug="$saved_debug"
25061         rm -f $DIR/$tfile
25062 }
25063 test_399a() { # LU-7655 for OST fake write
25064         remote_ost_nodsh && skip "remote OST with nodsh"
25065
25066         test_fake_rw write
25067 }
25068 run_test 399a "fake write should not be slower than normal write"
25069
25070 test_399b() { # LU-8726 for OST fake read
25071         remote_ost_nodsh && skip "remote OST with nodsh"
25072         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25073                 skip_env "ldiskfs only test"
25074         fi
25075
25076         test_fake_rw read
25077 }
25078 run_test 399b "fake read should not be slower than normal read"
25079
25080 test_400a() { # LU-1606, was conf-sanity test_74
25081         if ! which $CC > /dev/null 2>&1; then
25082                 skip_env "$CC is not installed"
25083         fi
25084
25085         local extra_flags=''
25086         local out=$TMP/$tfile
25087         local prefix=/usr/include/lustre
25088         local prog
25089
25090         # Oleg removes c files in his test rig so test if any c files exist
25091         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25092                 skip_env "Needed c test files are missing"
25093
25094         if ! [[ -d $prefix ]]; then
25095                 # Assume we're running in tree and fixup the include path.
25096                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25097                 extra_flags+=" -L$LUSTRE/utils/.lib"
25098         fi
25099
25100         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25101                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25102                         error "client api broken"
25103         done
25104         rm -f $out
25105 }
25106 run_test 400a "Lustre client api program can compile and link"
25107
25108 test_400b() { # LU-1606, LU-5011
25109         local header
25110         local out=$TMP/$tfile
25111         local prefix=/usr/include/linux/lustre
25112
25113         # We use a hard coded prefix so that this test will not fail
25114         # when run in tree. There are headers in lustre/include/lustre/
25115         # that are not packaged (like lustre_idl.h) and have more
25116         # complicated include dependencies (like config.h and lnet/types.h).
25117         # Since this test about correct packaging we just skip them when
25118         # they don't exist (see below) rather than try to fixup cppflags.
25119
25120         if ! which $CC > /dev/null 2>&1; then
25121                 skip_env "$CC is not installed"
25122         fi
25123
25124         for header in $prefix/*.h; do
25125                 if ! [[ -f "$header" ]]; then
25126                         continue
25127                 fi
25128
25129                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25130                         continue # lustre_ioctl.h is internal header
25131                 fi
25132
25133                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25134                         error "cannot compile '$header'"
25135         done
25136         rm -f $out
25137 }
25138 run_test 400b "packaged headers can be compiled"
25139
25140 test_401a() { #LU-7437
25141         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25142         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25143
25144         #count the number of parameters by "list_param -R"
25145         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25146         #count the number of parameters by listing proc files
25147         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25148         echo "proc_dirs='$proc_dirs'"
25149         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25150         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25151                       sort -u | wc -l)
25152
25153         [ $params -eq $procs ] ||
25154                 error "found $params parameters vs. $procs proc files"
25155
25156         # test the list_param -D option only returns directories
25157         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25158         #count the number of parameters by listing proc directories
25159         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25160                 sort -u | wc -l)
25161
25162         [ $params -eq $procs ] ||
25163                 error "found $params parameters vs. $procs proc files"
25164 }
25165 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25166
25167 test_401b() {
25168         # jobid_var may not allow arbitrary values, so use jobid_name
25169         # if available
25170         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25171                 local testname=jobid_name tmp='testing%p'
25172         else
25173                 local testname=jobid_var tmp=testing
25174         fi
25175
25176         local save=$($LCTL get_param -n $testname)
25177
25178         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25179                 error "no error returned when setting bad parameters"
25180
25181         local jobid_new=$($LCTL get_param -n foe $testname baz)
25182         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25183
25184         $LCTL set_param -n fog=bam $testname=$save bat=fog
25185         local jobid_old=$($LCTL get_param -n foe $testname bag)
25186         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25187 }
25188 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25189
25190 test_401c() {
25191         # jobid_var may not allow arbitrary values, so use jobid_name
25192         # if available
25193         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25194                 local testname=jobid_name
25195         else
25196                 local testname=jobid_var
25197         fi
25198
25199         local jobid_var_old=$($LCTL get_param -n $testname)
25200         local jobid_var_new
25201
25202         $LCTL set_param $testname= &&
25203                 error "no error returned for 'set_param a='"
25204
25205         jobid_var_new=$($LCTL get_param -n $testname)
25206         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25207                 error "$testname was changed by setting without value"
25208
25209         $LCTL set_param $testname &&
25210                 error "no error returned for 'set_param a'"
25211
25212         jobid_var_new=$($LCTL get_param -n $testname)
25213         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25214                 error "$testname was changed by setting without value"
25215 }
25216 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25217
25218 test_401d() {
25219         # jobid_var may not allow arbitrary values, so use jobid_name
25220         # if available
25221         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25222                 local testname=jobid_name new_value='foo=bar%p'
25223         else
25224                 local testname=jobid_var new_valuie=foo=bar
25225         fi
25226
25227         local jobid_var_old=$($LCTL get_param -n $testname)
25228         local jobid_var_new
25229
25230         $LCTL set_param $testname=$new_value ||
25231                 error "'set_param a=b' did not accept a value containing '='"
25232
25233         jobid_var_new=$($LCTL get_param -n $testname)
25234         [[ "$jobid_var_new" == "$new_value" ]] ||
25235                 error "'set_param a=b' failed on a value containing '='"
25236
25237         # Reset the $testname to test the other format
25238         $LCTL set_param $testname=$jobid_var_old
25239         jobid_var_new=$($LCTL get_param -n $testname)
25240         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25241                 error "failed to reset $testname"
25242
25243         $LCTL set_param $testname $new_value ||
25244                 error "'set_param a b' did not accept a value containing '='"
25245
25246         jobid_var_new=$($LCTL get_param -n $testname)
25247         [[ "$jobid_var_new" == "$new_value" ]] ||
25248                 error "'set_param a b' failed on a value containing '='"
25249
25250         $LCTL set_param $testname $jobid_var_old
25251         jobid_var_new=$($LCTL get_param -n $testname)
25252         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25253                 error "failed to reset $testname"
25254 }
25255 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25256
25257 test_401e() { # LU-14779
25258         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25259                 error "lctl list_param MGC* failed"
25260         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25261         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25262                 error "lctl get_param lru_size failed"
25263 }
25264 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25265
25266 test_402() {
25267         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25268         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25269                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25270         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25271                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25272                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25273         remote_mds_nodsh && skip "remote MDS with nodsh"
25274
25275         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25276 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25277         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25278         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25279                 echo "Touch failed - OK"
25280 }
25281 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25282
25283 test_403() {
25284         local file1=$DIR/$tfile.1
25285         local file2=$DIR/$tfile.2
25286         local tfile=$TMP/$tfile
25287
25288         rm -f $file1 $file2 $tfile
25289
25290         touch $file1
25291         ln $file1 $file2
25292
25293         # 30 sec OBD_TIMEOUT in ll_getattr()
25294         # right before populating st_nlink
25295         $LCTL set_param fail_loc=0x80001409
25296         stat -c %h $file1 > $tfile &
25297
25298         # create an alias, drop all locks and reclaim the dentry
25299         < $file2
25300         cancel_lru_locks mdc
25301         cancel_lru_locks osc
25302         sysctl -w vm.drop_caches=2
25303
25304         wait
25305
25306         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25307
25308         rm -f $tfile $file1 $file2
25309 }
25310 run_test 403 "i_nlink should not drop to zero due to aliasing"
25311
25312 test_404() { # LU-6601
25313         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25314                 skip "Need server version newer than 2.8.52"
25315         remote_mds_nodsh && skip "remote MDS with nodsh"
25316
25317         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25318                 awk '/osp .*-osc-MDT/ { print $4}')
25319
25320         local osp
25321         for osp in $mosps; do
25322                 echo "Deactivate: " $osp
25323                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25324                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25325                         awk -vp=$osp '$4 == p { print $2 }')
25326                 [ $stat = IN ] || {
25327                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25328                         error "deactivate error"
25329                 }
25330                 echo "Activate: " $osp
25331                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25332                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25333                         awk -vp=$osp '$4 == p { print $2 }')
25334                 [ $stat = UP ] || {
25335                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25336                         error "activate error"
25337                 }
25338         done
25339 }
25340 run_test 404 "validate manual {de}activated works properly for OSPs"
25341
25342 test_405() {
25343         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25344         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25345                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25346                         skip "Layout swap lock is not supported"
25347
25348         check_swap_layouts_support
25349         check_swap_layout_no_dom $DIR
25350
25351         test_mkdir $DIR/$tdir
25352         swap_lock_test -d $DIR/$tdir ||
25353                 error "One layout swap locked test failed"
25354 }
25355 run_test 405 "Various layout swap lock tests"
25356
25357 test_406() {
25358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25359         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25360         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25362         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25363                 skip "Need MDS version at least 2.8.50"
25364
25365         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25366         local test_pool=$TESTNAME
25367
25368         pool_add $test_pool || error "pool_add failed"
25369         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25370                 error "pool_add_targets failed"
25371
25372         save_layout_restore_at_exit $MOUNT
25373
25374         # parent set default stripe count only, child will stripe from both
25375         # parent and fs default
25376         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25377                 error "setstripe $MOUNT failed"
25378         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25379         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25380         for i in $(seq 10); do
25381                 local f=$DIR/$tdir/$tfile.$i
25382                 touch $f || error "touch failed"
25383                 local count=$($LFS getstripe -c $f)
25384                 [ $count -eq $OSTCOUNT ] ||
25385                         error "$f stripe count $count != $OSTCOUNT"
25386                 local offset=$($LFS getstripe -i $f)
25387                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25388                 local size=$($LFS getstripe -S $f)
25389                 [ $size -eq $((def_stripe_size * 2)) ] ||
25390                         error "$f stripe size $size != $((def_stripe_size * 2))"
25391                 local pool=$($LFS getstripe -p $f)
25392                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25393         done
25394
25395         # change fs default striping, delete parent default striping, now child
25396         # will stripe from new fs default striping only
25397         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25398                 error "change $MOUNT default stripe failed"
25399         $LFS setstripe -c 0 $DIR/$tdir ||
25400                 error "delete $tdir default stripe failed"
25401         for i in $(seq 11 20); do
25402                 local f=$DIR/$tdir/$tfile.$i
25403                 touch $f || error "touch $f failed"
25404                 local count=$($LFS getstripe -c $f)
25405                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25406                 local offset=$($LFS getstripe -i $f)
25407                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25408                 local size=$($LFS getstripe -S $f)
25409                 [ $size -eq $def_stripe_size ] ||
25410                         error "$f stripe size $size != $def_stripe_size"
25411                 local pool=$($LFS getstripe -p $f)
25412                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25413         done
25414
25415         unlinkmany $DIR/$tdir/$tfile. 1 20
25416
25417         local f=$DIR/$tdir/$tfile
25418         pool_remove_all_targets $test_pool $f
25419         pool_remove $test_pool $f
25420 }
25421 run_test 406 "DNE support fs default striping"
25422
25423 test_407() {
25424         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25425         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25426                 skip "Need MDS version at least 2.8.55"
25427         remote_mds_nodsh && skip "remote MDS with nodsh"
25428
25429         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25430                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25431         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25432                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25433         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25434
25435         #define OBD_FAIL_DT_TXN_STOP    0x2019
25436         for idx in $(seq $MDSCOUNT); do
25437                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25438         done
25439         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25440         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25441                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25442         true
25443 }
25444 run_test 407 "transaction fail should cause operation fail"
25445
25446 test_408() {
25447         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25448
25449         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25450         lctl set_param fail_loc=0x8000040a
25451         # let ll_prepare_partial_page() fail
25452         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25453
25454         rm -f $DIR/$tfile
25455
25456         # create at least 100 unused inodes so that
25457         # shrink_icache_memory(0) should not return 0
25458         touch $DIR/$tfile-{0..100}
25459         rm -f $DIR/$tfile-{0..100}
25460         sync
25461
25462         echo 2 > /proc/sys/vm/drop_caches
25463 }
25464 run_test 408 "drop_caches should not hang due to page leaks"
25465
25466 test_409()
25467 {
25468         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25469
25470         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25471         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25472         touch $DIR/$tdir/guard || error "(2) Fail to create"
25473
25474         local PREFIX=$(str_repeat 'A' 128)
25475         echo "Create 1K hard links start at $(date)"
25476         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25477                 error "(3) Fail to hard link"
25478
25479         echo "Links count should be right although linkEA overflow"
25480         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25481         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25482         [ $linkcount -eq 1001 ] ||
25483                 error "(5) Unexpected hard links count: $linkcount"
25484
25485         echo "List all links start at $(date)"
25486         ls -l $DIR/$tdir/foo > /dev/null ||
25487                 error "(6) Fail to list $DIR/$tdir/foo"
25488
25489         echo "Unlink hard links start at $(date)"
25490         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25491                 error "(7) Fail to unlink"
25492         echo "Unlink hard links finished at $(date)"
25493 }
25494 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25495
25496 test_410()
25497 {
25498         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25499                 skip "Need client version at least 2.9.59"
25500         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25501                 skip "Need MODULES build"
25502
25503         # Create a file, and stat it from the kernel
25504         local testfile=$DIR/$tfile
25505         touch $testfile
25506
25507         local run_id=$RANDOM
25508         local my_ino=$(stat --format "%i" $testfile)
25509
25510         # Try to insert the module. This will always fail as the
25511         # module is designed to not be inserted.
25512         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25513             &> /dev/null
25514
25515         # Anything but success is a test failure
25516         dmesg | grep -q \
25517             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25518             error "no inode match"
25519 }
25520 run_test 410 "Test inode number returned from kernel thread"
25521
25522 cleanup_test411_cgroup() {
25523         trap 0
25524         rmdir "$1"
25525 }
25526
25527 test_411() {
25528         local cg_basedir=/sys/fs/cgroup/memory
25529         # LU-9966
25530         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25531                 skip "no setup for cgroup"
25532
25533         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25534                 error "test file creation failed"
25535         cancel_lru_locks osc
25536
25537         # Create a very small memory cgroup to force a slab allocation error
25538         local cgdir=$cg_basedir/osc_slab_alloc
25539         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25540         trap "cleanup_test411_cgroup $cgdir" EXIT
25541         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25542         echo 1M > $cgdir/memory.limit_in_bytes
25543
25544         # Should not LBUG, just be killed by oom-killer
25545         # dd will return 0 even allocation failure in some environment.
25546         # So don't check return value
25547         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25548         cleanup_test411_cgroup $cgdir
25549
25550         return 0
25551 }
25552 run_test 411 "Slab allocation error with cgroup does not LBUG"
25553
25554 test_412() {
25555         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25556         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25557                 skip "Need server version at least 2.10.55"
25558
25559         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25560                 error "mkdir failed"
25561         $LFS getdirstripe $DIR/$tdir
25562         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25563         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25564                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25565         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25566         [ $stripe_count -eq 2 ] ||
25567                 error "expect 2 get $stripe_count"
25568
25569         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25570
25571         local index
25572         local index2
25573
25574         # subdirs should be on the same MDT as parent
25575         for i in $(seq 0 $((MDSCOUNT - 1))); do
25576                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25577                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25578                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25579                 (( index == i )) || error "mdt$i/sub on MDT$index"
25580         done
25581
25582         # stripe offset -1, ditto
25583         for i in {1..10}; do
25584                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25585                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25586                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25587                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25588                 (( index == index2 )) ||
25589                         error "qos$i on MDT$index, sub on MDT$index2"
25590         done
25591
25592         local testdir=$DIR/$tdir/inherit
25593
25594         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25595         # inherit 2 levels
25596         for i in 1 2; do
25597                 testdir=$testdir/s$i
25598                 mkdir $testdir || error "mkdir $testdir failed"
25599                 index=$($LFS getstripe -m $testdir)
25600                 (( index == 1 )) ||
25601                         error "$testdir on MDT$index"
25602         done
25603
25604         # not inherit any more
25605         testdir=$testdir/s3
25606         mkdir $testdir || error "mkdir $testdir failed"
25607         getfattr -d -m dmv $testdir | grep dmv &&
25608                 error "default LMV set on $testdir" || true
25609 }
25610 run_test 412 "mkdir on specific MDTs"
25611
25612 TEST413_COUNT=${TEST413_COUNT:-200}
25613 generate_uneven_mdts() {
25614         local threshold=$1
25615         local lmv_qos_maxage
25616         local lod_qos_maxage
25617         local ffree
25618         local bavail
25619         local max
25620         local min
25621         local max_index
25622         local min_index
25623         local tmp
25624         local i
25625
25626         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25627         $LCTL set_param lmv.*.qos_maxage=1
25628         stack_trap "$LCTL set_param \
25629                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25630         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25631                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25632         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25633                 lod.*.mdt_qos_maxage=1
25634         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25635                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25636
25637         echo
25638         echo "Check for uneven MDTs: "
25639
25640         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25641         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25642         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25643
25644         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25645         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25646         max_index=0
25647         min_index=0
25648         for ((i = 1; i < ${#ffree[@]}; i++)); do
25649                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25650                 if [ $tmp -gt $max ]; then
25651                         max=$tmp
25652                         max_index=$i
25653                 fi
25654                 if [ $tmp -lt $min ]; then
25655                         min=$tmp
25656                         min_index=$i
25657                 fi
25658         done
25659
25660         (( ${ffree[min_index]} > 0 )) ||
25661                 skip "no free files in MDT$min_index"
25662         (( ${ffree[min_index]} < 10000000 )) ||
25663                 skip "too many free files in MDT$min_index"
25664
25665         # Check if we need to generate uneven MDTs
25666         local diff=$(((max - min) * 100 / min))
25667         local testdir=$DIR/$tdir-fillmdt
25668         local start
25669
25670         i=0
25671         while (( diff < threshold )); do
25672                 mkdir -p $testdir
25673                 # generate uneven MDTs, create till $threshold% diff
25674                 echo -n "weight diff=$diff% must be > $threshold% ..."
25675                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25676                 testdir=$DIR/$tdir-fillmdt/$i
25677                 [ -d $testdir ] && continue
25678                 $LFS mkdir -i $min_index $testdir ||
25679                         error "mkdir $testdir failed"
25680                 $LFS setstripe -E 1M -L mdt $testdir ||
25681                         error "setstripe $testdir failed"
25682                 start=$SECONDS
25683                 for ((F=0; F < TEST413_COUNT; F++)); do
25684                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25685                                 /dev/null 2>&1 || error "dd $F failed"
25686                 done
25687                 sync; sleep 1; sync
25688
25689                 # wait for QOS to update
25690                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25691
25692                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25693                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25694                 max=$(((${ffree[max_index]} >> 8) *
25695                         (${bavail[max_index]} * bsize >> 16)))
25696                 min=$(((${ffree[min_index]} >> 8) *
25697                         (${bavail[min_index]} * bsize >> 16)))
25698                 diff=$(((max - min) * 100 / min))
25699                 i=$((i + 1))
25700         done
25701
25702         echo "MDT filesfree available: ${ffree[*]}"
25703         echo "MDT blocks available: ${bavail[*]}"
25704         echo "weight diff=$diff%"
25705 }
25706
25707 test_qos_mkdir() {
25708         local mkdir_cmd=$1
25709         local stripe_count=$2
25710         local mdts=$(comma_list $(mdts_nodes))
25711
25712         local testdir
25713         local lmv_qos_prio_free
25714         local lmv_qos_threshold_rr
25715         local lmv_qos_maxage
25716         local lod_qos_prio_free
25717         local lod_qos_threshold_rr
25718         local lod_qos_maxage
25719         local count
25720         local i
25721
25722         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25723         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25724         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25725                 head -n1)
25726         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25727         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25728         stack_trap "$LCTL set_param \
25729                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25730         stack_trap "$LCTL set_param \
25731                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25732         stack_trap "$LCTL set_param \
25733                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25734
25735         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25736                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25737         lod_qos_prio_free=${lod_qos_prio_free%%%}
25738         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25739                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25740         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25741         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25742                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25743         stack_trap "do_nodes $mdts $LCTL set_param \
25744                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25745         stack_trap "do_nodes $mdts $LCTL set_param \
25746                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25747         stack_trap "do_nodes $mdts $LCTL set_param \
25748                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25749
25750         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25751         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25752
25753         testdir=$DIR/$tdir-s$stripe_count/rr
25754
25755         local stripe_index=$($LFS getstripe -m $testdir)
25756         local test_mkdir_rr=true
25757
25758         getfattr -d -m dmv -e hex $testdir | grep dmv
25759         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25760                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25761                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25762                         test_mkdir_rr=false
25763         fi
25764
25765         echo
25766         $test_mkdir_rr &&
25767                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25768                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25769
25770         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25771         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25772                 eval $mkdir_cmd $testdir/subdir$i ||
25773                         error "$mkdir_cmd subdir$i failed"
25774         done
25775
25776         for (( i = 0; i < $MDSCOUNT; i++ )); do
25777                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25778                 echo "$count directories created on MDT$i"
25779                 if $test_mkdir_rr; then
25780                         (( $count == 100 )) ||
25781                                 error "subdirs are not evenly distributed"
25782                 elif (( $i == $stripe_index )); then
25783                         (( $count == 100 * MDSCOUNT )) ||
25784                                 error "$count subdirs created on MDT$i"
25785                 else
25786                         (( $count == 0 )) ||
25787                                 error "$count subdirs created on MDT$i"
25788                 fi
25789
25790                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25791                         count=$($LFS getdirstripe $testdir/* |
25792                                 grep -c -P "^\s+$i\t")
25793                         echo "$count stripes created on MDT$i"
25794                         # deviation should < 5% of average
25795                         (( $count >= 95 * stripe_count &&
25796                            $count <= 105 * stripe_count)) ||
25797                                 error "stripes are not evenly distributed"
25798                 fi
25799         done
25800
25801         echo
25802         echo "Check for uneven MDTs: "
25803
25804         local ffree
25805         local bavail
25806         local max
25807         local min
25808         local max_index
25809         local min_index
25810         local tmp
25811
25812         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25813         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25814         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25815
25816         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25817         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25818         max_index=0
25819         min_index=0
25820         for ((i = 1; i < ${#ffree[@]}; i++)); do
25821                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25822                 if [ $tmp -gt $max ]; then
25823                         max=$tmp
25824                         max_index=$i
25825                 fi
25826                 if [ $tmp -lt $min ]; then
25827                         min=$tmp
25828                         min_index=$i
25829                 fi
25830         done
25831
25832         (( ${ffree[min_index]} > 0 )) ||
25833                 skip "no free files in MDT$min_index"
25834         (( ${ffree[min_index]} < 10000000 )) ||
25835                 skip "too many free files in MDT$min_index"
25836
25837         echo "MDT filesfree available: ${ffree[*]}"
25838         echo "MDT blocks available: ${bavail[*]}"
25839         echo "weight diff=$(((max - min) * 100 / min))%"
25840         echo
25841         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25842
25843         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25844         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25845         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25846         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25847         # decrease statfs age, so that it can be updated in time
25848         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25849         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25850
25851         sleep 1
25852
25853         testdir=$DIR/$tdir-s$stripe_count/qos
25854         local num=200
25855
25856         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25857         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25858                 eval $mkdir_cmd $testdir/subdir$i ||
25859                         error "$mkdir_cmd subdir$i failed"
25860         done
25861
25862         max=0
25863         for (( i = 0; i < $MDSCOUNT; i++ )); do
25864                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25865                 (( count > max )) && max=$count
25866                 echo "$count directories created on MDT$i"
25867         done
25868
25869         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25870
25871         # D-value should > 10% of averge
25872         (( max - min > num / 10 )) ||
25873                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25874
25875         # ditto for stripes
25876         if (( stripe_count > 1 )); then
25877                 max=0
25878                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25879                         count=$($LFS getdirstripe $testdir/* |
25880                                 grep -c -P "^\s+$i\t")
25881                         (( count > max )) && max=$count
25882                         echo "$count stripes created on MDT$i"
25883                 done
25884
25885                 min=$($LFS getdirstripe $testdir/* |
25886                         grep -c -P "^\s+$min_index\t")
25887                 (( max - min > num * stripe_count / 10 )) ||
25888                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25889         fi
25890 }
25891
25892 most_full_mdt() {
25893         local ffree
25894         local bavail
25895         local bsize
25896         local min
25897         local min_index
25898         local tmp
25899
25900         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25901         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25902         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25903
25904         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25905         min_index=0
25906         for ((i = 1; i < ${#ffree[@]}; i++)); do
25907                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25908                 (( tmp < min )) && min=$tmp && min_index=$i
25909         done
25910
25911         echo -n $min_index
25912 }
25913
25914 test_413a() {
25915         [ $MDSCOUNT -lt 2 ] &&
25916                 skip "We need at least 2 MDTs for this test"
25917
25918         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25919                 skip "Need server version at least 2.12.52"
25920
25921         local stripe_count
25922
25923         generate_uneven_mdts 100
25924         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25925                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25926                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25927                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25928                         error "mkdir failed"
25929                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25930         done
25931 }
25932 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25933
25934 test_413b() {
25935         [ $MDSCOUNT -lt 2 ] &&
25936                 skip "We need at least 2 MDTs for this test"
25937
25938         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25939                 skip "Need server version at least 2.12.52"
25940
25941         local testdir
25942         local stripe_count
25943
25944         generate_uneven_mdts 100
25945         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25946                 testdir=$DIR/$tdir-s$stripe_count
25947                 mkdir $testdir || error "mkdir $testdir failed"
25948                 mkdir $testdir/rr || error "mkdir rr failed"
25949                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25950                         error "mkdir qos failed"
25951                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25952                         $testdir/rr || error "setdirstripe rr failed"
25953                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25954                         error "setdirstripe failed"
25955                 test_qos_mkdir "mkdir" $stripe_count
25956         done
25957 }
25958 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25959
25960 test_413c() {
25961         (( $MDSCOUNT >= 2 )) ||
25962                 skip "We need at least 2 MDTs for this test"
25963
25964         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25965                 skip "Need server version at least 2.14.51"
25966
25967         local testdir
25968         local inherit
25969         local inherit_rr
25970
25971         testdir=$DIR/${tdir}-s1
25972         mkdir $testdir || error "mkdir $testdir failed"
25973         mkdir $testdir/rr || error "mkdir rr failed"
25974         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25975         # default max_inherit is -1, default max_inherit_rr is 0
25976         $LFS setdirstripe -D -c 1 $testdir/rr ||
25977                 error "setdirstripe rr failed"
25978         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25979                 error "setdirstripe qos failed"
25980         test_qos_mkdir "mkdir" 1
25981
25982         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25983         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25984         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25985         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25986         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25987
25988         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25989         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25990         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25991         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25992         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25993         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25994         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25995                 error "level2 shouldn't have default LMV" || true
25996 }
25997 run_test 413c "mkdir with default LMV max inherit rr"
25998
25999 test_413d() {
26000         (( MDSCOUNT >= 2 )) ||
26001                 skip "We need at least 2 MDTs for this test"
26002
26003         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26004                 skip "Need server version at least 2.14.51"
26005
26006         local lmv_qos_threshold_rr
26007
26008         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26009                 head -n1)
26010         stack_trap "$LCTL set_param \
26011                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26012
26013         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26014         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26015         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26016                 error "$tdir shouldn't have default LMV"
26017         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26018                 error "mkdir sub failed"
26019
26020         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26021
26022         (( count == 100 )) || error "$count subdirs on MDT0"
26023 }
26024 run_test 413d "inherit ROOT default LMV"
26025
26026 test_413e() {
26027         (( MDSCOUNT >= 2 )) ||
26028                 skip "We need at least 2 MDTs for this test"
26029         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26030                 skip "Need server version at least 2.14.55"
26031
26032         local testdir=$DIR/$tdir
26033         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26034         local max_inherit
26035         local sub_max_inherit
26036
26037         mkdir -p $testdir || error "failed to create $testdir"
26038
26039         # set default max-inherit to -1 if stripe count is 0 or 1
26040         $LFS setdirstripe -D -c 1 $testdir ||
26041                 error "failed to set default LMV"
26042         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26043         (( max_inherit == -1 )) ||
26044                 error "wrong max_inherit value $max_inherit"
26045
26046         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26047         $LFS setdirstripe -D -c -1 $testdir ||
26048                 error "failed to set default LMV"
26049         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26050         (( max_inherit > 0 )) ||
26051                 error "wrong max_inherit value $max_inherit"
26052
26053         # and the subdir will decrease the max_inherit by 1
26054         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26055         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26056         (( sub_max_inherit == max_inherit - 1)) ||
26057                 error "wrong max-inherit of subdir $sub_max_inherit"
26058
26059         # check specified --max-inherit and warning message
26060         stack_trap "rm -f $tmpfile"
26061         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26062                 error "failed to set default LMV"
26063         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26064         (( max_inherit == -1 )) ||
26065                 error "wrong max_inherit value $max_inherit"
26066
26067         # check the warning messages
26068         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26069                 error "failed to detect warning string"
26070         fi
26071 }
26072 run_test 413e "check default max-inherit value"
26073
26074 test_fs_dmv_inherit()
26075 {
26076         local testdir=$DIR/$tdir
26077
26078         local count
26079         local inherit
26080         local inherit_rr
26081
26082         for i in 1 2 3; do
26083                 mkdir $testdir || error "mkdir $testdir failed"
26084                 count=$($LFS getdirstripe -D -c $testdir)
26085                 (( count == 1 )) ||
26086                         error "$testdir default LMV count mismatch $count != 1"
26087                 inherit=$($LFS getdirstripe -D -X $testdir)
26088                 (( inherit == 3 - i )) ||
26089                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26090                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26091                 (( inherit_rr == 3 - i )) ||
26092                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26093                 testdir=$testdir/sub
26094         done
26095
26096         mkdir $testdir || error "mkdir $testdir failed"
26097         count=$($LFS getdirstripe -D -c $testdir)
26098         (( count == 0 )) ||
26099                 error "$testdir default LMV count not zero: $count"
26100 }
26101
26102 test_413f() {
26103         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26104
26105         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26106                 skip "Need server version at least 2.14.55"
26107
26108         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26109                 error "dump $DIR default LMV failed"
26110         stack_trap "setfattr --restore=$TMP/dmv.ea"
26111
26112         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26113                 error "set $DIR default LMV failed"
26114
26115         test_fs_dmv_inherit
26116 }
26117 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26118
26119 test_413g() {
26120         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26121
26122         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26123         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26124                 error "dump $DIR default LMV failed"
26125         stack_trap "setfattr --restore=$TMP/dmv.ea"
26126
26127         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26128                 error "set $DIR default LMV failed"
26129
26130         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26131                 error "mount $MOUNT2 failed"
26132         stack_trap "umount_client $MOUNT2"
26133
26134         local saved_DIR=$DIR
26135
26136         export DIR=$MOUNT2
26137
26138         stack_trap "export DIR=$saved_DIR"
26139
26140         # first check filesystem-wide default LMV inheritance
26141         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26142
26143         # then check subdirs are spread to all MDTs
26144         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26145
26146         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26147
26148         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26149 }
26150 run_test 413g "enforce ROOT default LMV on subdir mount"
26151
26152 test_413h() {
26153         (( MDSCOUNT >= 2 )) ||
26154                 skip "We need at least 2 MDTs for this test"
26155
26156         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26157                 skip "Need server version at least 2.15.50.6"
26158
26159         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26160
26161         stack_trap "$LCTL set_param \
26162                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26163         $LCTL set_param lmv.*.qos_maxage=1
26164
26165         local depth=5
26166         local rr_depth=4
26167         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26168         local count=$((MDSCOUNT * 20))
26169
26170         generate_uneven_mdts 50
26171
26172         mkdir -p $dir || error "mkdir $dir failed"
26173         stack_trap "rm -rf $dir"
26174         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26175                 --max-inherit-rr=$rr_depth $dir
26176
26177         for ((d=0; d < depth + 2; d++)); do
26178                 log "dir=$dir:"
26179                 for ((sub=0; sub < count; sub++)); do
26180                         mkdir $dir/d$sub
26181                 done
26182                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26183                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26184                 # subdirs within $rr_depth should be created round-robin
26185                 if (( d < rr_depth )); then
26186                         (( ${num[0]} != count )) ||
26187                                 error "all objects created on MDT ${num[1]}"
26188                 fi
26189
26190                 dir=$dir/d0
26191         done
26192 }
26193 run_test 413h "don't stick to parent for round-robin dirs"
26194
26195 test_413z() {
26196         local pids=""
26197         local subdir
26198         local pid
26199
26200         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26201                 unlinkmany $subdir/f. $TEST413_COUNT &
26202                 pids="$pids $!"
26203         done
26204
26205         for pid in $pids; do
26206                 wait $pid
26207         done
26208 }
26209 run_test 413z "413 test cleanup"
26210
26211 test_414() {
26212 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26213         $LCTL set_param fail_loc=0x80000521
26214         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26215         rm -f $DIR/$tfile
26216 }
26217 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26218
26219 test_415() {
26220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26221         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26222                 skip "Need server version at least 2.11.52"
26223
26224         # LU-11102
26225         local total
26226         local setattr_pid
26227         local start_time
26228         local end_time
26229         local duration
26230
26231         total=500
26232         # this test may be slow on ZFS
26233         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26234
26235         # though this test is designed for striped directory, let's test normal
26236         # directory too since lock is always saved as CoS lock.
26237         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26238         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26239
26240         (
26241                 while true; do
26242                         touch $DIR/$tdir
26243                 done
26244         ) &
26245         setattr_pid=$!
26246
26247         start_time=$(date +%s)
26248         for i in $(seq $total); do
26249                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26250                         > /dev/null
26251         done
26252         end_time=$(date +%s)
26253         duration=$((end_time - start_time))
26254
26255         kill -9 $setattr_pid
26256
26257         echo "rename $total files took $duration sec"
26258         [ $duration -lt 100 ] || error "rename took $duration sec"
26259 }
26260 run_test 415 "lock revoke is not missing"
26261
26262 test_416() {
26263         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26264                 skip "Need server version at least 2.11.55"
26265
26266         # define OBD_FAIL_OSD_TXN_START    0x19a
26267         do_facet mds1 lctl set_param fail_loc=0x19a
26268
26269         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26270
26271         true
26272 }
26273 run_test 416 "transaction start failure won't cause system hung"
26274
26275 cleanup_417() {
26276         trap 0
26277         do_nodes $(comma_list $(mdts_nodes)) \
26278                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26279         do_nodes $(comma_list $(mdts_nodes)) \
26280                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26281         do_nodes $(comma_list $(mdts_nodes)) \
26282                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26283 }
26284
26285 test_417() {
26286         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26287         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26288                 skip "Need MDS version at least 2.11.56"
26289
26290         trap cleanup_417 RETURN EXIT
26291
26292         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26293         do_nodes $(comma_list $(mdts_nodes)) \
26294                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26295         $LFS migrate -m 0 $DIR/$tdir.1 &&
26296                 error "migrate dir $tdir.1 should fail"
26297
26298         do_nodes $(comma_list $(mdts_nodes)) \
26299                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26300         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26301                 error "create remote dir $tdir.2 should fail"
26302
26303         do_nodes $(comma_list $(mdts_nodes)) \
26304                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26305         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26306                 error "create striped dir $tdir.3 should fail"
26307         true
26308 }
26309 run_test 417 "disable remote dir, striped dir and dir migration"
26310
26311 # Checks that the outputs of df [-i] and lfs df [-i] match
26312 #
26313 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26314 check_lfs_df() {
26315         local dir=$2
26316         local inodes
26317         local df_out
26318         local lfs_df_out
26319         local count
26320         local passed=false
26321
26322         # blocks or inodes
26323         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26324
26325         for count in {1..100}; do
26326                 do_nodes "$CLIENTS" \
26327                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26328                 sync; sleep 0.2
26329
26330                 # read the lines of interest
26331                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26332                         error "df $inodes $dir | tail -n +2 failed"
26333                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26334                         error "lfs df $inodes $dir | grep summary: failed"
26335
26336                 # skip first substrings of each output as they are different
26337                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26338                 # compare the two outputs
26339                 passed=true
26340                 #  skip "available" on MDT until LU-13997 is fixed.
26341                 #for i in {1..5}; do
26342                 for i in 1 2 4 5; do
26343                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26344                 done
26345                 $passed && break
26346         done
26347
26348         if ! $passed; then
26349                 df -P $inodes $dir
26350                 echo
26351                 lfs df $inodes $dir
26352                 error "df and lfs df $1 output mismatch: "      \
26353                       "df ${inodes}: ${df_out[*]}, "            \
26354                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26355         fi
26356 }
26357
26358 test_418() {
26359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26360
26361         local dir=$DIR/$tdir
26362         local numfiles=$((RANDOM % 4096 + 2))
26363         local numblocks=$((RANDOM % 256 + 1))
26364
26365         wait_delete_completed
26366         test_mkdir $dir
26367
26368         # check block output
26369         check_lfs_df blocks $dir
26370         # check inode output
26371         check_lfs_df inodes $dir
26372
26373         # create a single file and retest
26374         echo "Creating a single file and testing"
26375         createmany -o $dir/$tfile- 1 &>/dev/null ||
26376                 error "creating 1 file in $dir failed"
26377         check_lfs_df blocks $dir
26378         check_lfs_df inodes $dir
26379
26380         # create a random number of files
26381         echo "Creating $((numfiles - 1)) files and testing"
26382         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26383                 error "creating $((numfiles - 1)) files in $dir failed"
26384
26385         # write a random number of blocks to the first test file
26386         echo "Writing $numblocks 4K blocks and testing"
26387         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26388                 count=$numblocks &>/dev/null ||
26389                 error "dd to $dir/${tfile}-0 failed"
26390
26391         # retest
26392         check_lfs_df blocks $dir
26393         check_lfs_df inodes $dir
26394
26395         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26396                 error "unlinking $numfiles files in $dir failed"
26397 }
26398 run_test 418 "df and lfs df outputs match"
26399
26400 test_419()
26401 {
26402         local dir=$DIR/$tdir
26403
26404         mkdir -p $dir
26405         touch $dir/file
26406
26407         cancel_lru_locks mdc
26408
26409         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26410         $LCTL set_param fail_loc=0x1410
26411         cat $dir/file
26412         $LCTL set_param fail_loc=0
26413         rm -rf $dir
26414 }
26415 run_test 419 "Verify open file by name doesn't crash kernel"
26416
26417 test_420()
26418 {
26419         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26420                 skip "Need MDS version at least 2.12.53"
26421
26422         local SAVE_UMASK=$(umask)
26423         local dir=$DIR/$tdir
26424         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26425
26426         mkdir -p $dir
26427         umask 0000
26428         mkdir -m03777 $dir/testdir
26429         ls -dn $dir/testdir
26430         # Need to remove trailing '.' when SELinux is enabled
26431         local dirperms=$(ls -dn $dir/testdir |
26432                          awk '{ sub(/\.$/, "", $1); print $1}')
26433         [ $dirperms == "drwxrwsrwt" ] ||
26434                 error "incorrect perms on $dir/testdir"
26435
26436         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26437                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26438         ls -n $dir/testdir/testfile
26439         local fileperms=$(ls -n $dir/testdir/testfile |
26440                           awk '{ sub(/\.$/, "", $1); print $1}')
26441         [ $fileperms == "-rwxr-xr-x" ] ||
26442                 error "incorrect perms on $dir/testdir/testfile"
26443
26444         umask $SAVE_UMASK
26445 }
26446 run_test 420 "clear SGID bit on non-directories for non-members"
26447
26448 test_421a() {
26449         local cnt
26450         local fid1
26451         local fid2
26452
26453         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26454                 skip "Need MDS version at least 2.12.54"
26455
26456         test_mkdir $DIR/$tdir
26457         createmany -o $DIR/$tdir/f 3
26458         cnt=$(ls -1 $DIR/$tdir | wc -l)
26459         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26460
26461         fid1=$(lfs path2fid $DIR/$tdir/f1)
26462         fid2=$(lfs path2fid $DIR/$tdir/f2)
26463         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26464
26465         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26466         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26467
26468         cnt=$(ls -1 $DIR/$tdir | wc -l)
26469         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26470
26471         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26472         createmany -o $DIR/$tdir/f 3
26473         cnt=$(ls -1 $DIR/$tdir | wc -l)
26474         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26475
26476         fid1=$(lfs path2fid $DIR/$tdir/f1)
26477         fid2=$(lfs path2fid $DIR/$tdir/f2)
26478         echo "remove using fsname $FSNAME"
26479         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26480
26481         cnt=$(ls -1 $DIR/$tdir | wc -l)
26482         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26483 }
26484 run_test 421a "simple rm by fid"
26485
26486 test_421b() {
26487         local cnt
26488         local FID1
26489         local FID2
26490
26491         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26492                 skip "Need MDS version at least 2.12.54"
26493
26494         test_mkdir $DIR/$tdir
26495         createmany -o $DIR/$tdir/f 3
26496         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26497         MULTIPID=$!
26498
26499         FID1=$(lfs path2fid $DIR/$tdir/f1)
26500         FID2=$(lfs path2fid $DIR/$tdir/f2)
26501         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26502
26503         kill -USR1 $MULTIPID
26504         wait
26505
26506         cnt=$(ls $DIR/$tdir | wc -l)
26507         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26508 }
26509 run_test 421b "rm by fid on open file"
26510
26511 test_421c() {
26512         local cnt
26513         local FIDS
26514
26515         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26516                 skip "Need MDS version at least 2.12.54"
26517
26518         test_mkdir $DIR/$tdir
26519         createmany -o $DIR/$tdir/f 3
26520         touch $DIR/$tdir/$tfile
26521         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26522         cnt=$(ls -1 $DIR/$tdir | wc -l)
26523         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26524
26525         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26526         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26527
26528         cnt=$(ls $DIR/$tdir | wc -l)
26529         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26530 }
26531 run_test 421c "rm by fid against hardlinked files"
26532
26533 test_421d() {
26534         local cnt
26535         local FIDS
26536
26537         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26538                 skip "Need MDS version at least 2.12.54"
26539
26540         test_mkdir $DIR/$tdir
26541         createmany -o $DIR/$tdir/f 4097
26542         cnt=$(ls -1 $DIR/$tdir | wc -l)
26543         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26544
26545         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26546         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26547
26548         cnt=$(ls $DIR/$tdir | wc -l)
26549         rm -rf $DIR/$tdir
26550         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26551 }
26552 run_test 421d "rmfid en masse"
26553
26554 test_421e() {
26555         local cnt
26556         local FID
26557
26558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26559         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26560                 skip "Need MDS version at least 2.12.54"
26561
26562         mkdir -p $DIR/$tdir
26563         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26564         createmany -o $DIR/$tdir/striped_dir/f 512
26565         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26566         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26567
26568         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26569                 sed "s/[/][^:]*://g")
26570         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26571
26572         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26573         rm -rf $DIR/$tdir
26574         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26575 }
26576 run_test 421e "rmfid in DNE"
26577
26578 test_421f() {
26579         local cnt
26580         local FID
26581
26582         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26583                 skip "Need MDS version at least 2.12.54"
26584
26585         test_mkdir $DIR/$tdir
26586         touch $DIR/$tdir/f
26587         cnt=$(ls -1 $DIR/$tdir | wc -l)
26588         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26589
26590         FID=$(lfs path2fid $DIR/$tdir/f)
26591         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26592         # rmfid should fail
26593         cnt=$(ls -1 $DIR/$tdir | wc -l)
26594         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26595
26596         chmod a+rw $DIR/$tdir
26597         ls -la $DIR/$tdir
26598         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26599         # rmfid should fail
26600         cnt=$(ls -1 $DIR/$tdir | wc -l)
26601         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26602
26603         rm -f $DIR/$tdir/f
26604         $RUNAS touch $DIR/$tdir/f
26605         FID=$(lfs path2fid $DIR/$tdir/f)
26606         echo "rmfid as root"
26607         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26608         cnt=$(ls -1 $DIR/$tdir | wc -l)
26609         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26610
26611         rm -f $DIR/$tdir/f
26612         $RUNAS touch $DIR/$tdir/f
26613         cnt=$(ls -1 $DIR/$tdir | wc -l)
26614         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26615         FID=$(lfs path2fid $DIR/$tdir/f)
26616         # rmfid w/o user_fid2path mount option should fail
26617         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26618         cnt=$(ls -1 $DIR/$tdir | wc -l)
26619         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26620
26621         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26622         stack_trap "rmdir $tmpdir"
26623         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26624                 error "failed to mount client'"
26625         stack_trap "umount_client $tmpdir"
26626
26627         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26628         # rmfid should succeed
26629         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26630         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26631
26632         # rmfid shouldn't allow to remove files due to dir's permission
26633         chmod a+rwx $tmpdir/$tdir
26634         touch $tmpdir/$tdir/f
26635         ls -la $tmpdir/$tdir
26636         FID=$(lfs path2fid $tmpdir/$tdir/f)
26637         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26638         return 0
26639 }
26640 run_test 421f "rmfid checks permissions"
26641
26642 test_421g() {
26643         local cnt
26644         local FIDS
26645
26646         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26647         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26648                 skip "Need MDS version at least 2.12.54"
26649
26650         mkdir -p $DIR/$tdir
26651         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26652         createmany -o $DIR/$tdir/striped_dir/f 512
26653         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26654         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26655
26656         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26657                 sed "s/[/][^:]*://g")
26658
26659         rm -f $DIR/$tdir/striped_dir/f1*
26660         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26661         removed=$((512 - cnt))
26662
26663         # few files have been just removed, so we expect
26664         # rmfid to fail on their fids
26665         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26666         [ $removed != $errors ] && error "$errors != $removed"
26667
26668         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26669         rm -rf $DIR/$tdir
26670         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26671 }
26672 run_test 421g "rmfid to return errors properly"
26673
26674 test_422() {
26675         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26676         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26677         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26678         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26679         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26680
26681         local amc=$(at_max_get client)
26682         local amo=$(at_max_get mds1)
26683         local timeout=`lctl get_param -n timeout`
26684
26685         at_max_set 0 client
26686         at_max_set 0 mds1
26687
26688 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26689         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26690                         fail_val=$(((2*timeout + 10)*1000))
26691         touch $DIR/$tdir/d3/file &
26692         sleep 2
26693 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26694         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26695                         fail_val=$((2*timeout + 5))
26696         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26697         local pid=$!
26698         sleep 1
26699         kill -9 $pid
26700         sleep $((2 * timeout))
26701         echo kill $pid
26702         kill -9 $pid
26703         lctl mark touch
26704         touch $DIR/$tdir/d2/file3
26705         touch $DIR/$tdir/d2/file4
26706         touch $DIR/$tdir/d2/file5
26707
26708         wait
26709         at_max_set $amc client
26710         at_max_set $amo mds1
26711
26712         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26713         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26714                 error "Watchdog is always throttled"
26715 }
26716 run_test 422 "kill a process with RPC in progress"
26717
26718 stat_test() {
26719     df -h $MOUNT &
26720     df -h $MOUNT &
26721     df -h $MOUNT &
26722     df -h $MOUNT &
26723     df -h $MOUNT &
26724     df -h $MOUNT &
26725 }
26726
26727 test_423() {
26728     local _stats
26729     # ensure statfs cache is expired
26730     sleep 2;
26731
26732     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26733     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26734
26735     return 0
26736 }
26737 run_test 423 "statfs should return a right data"
26738
26739 test_424() {
26740 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26741         $LCTL set_param fail_loc=0x80000522
26742         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26743         rm -f $DIR/$tfile
26744 }
26745 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26746
26747 test_425() {
26748         test_mkdir -c -1 $DIR/$tdir
26749         $LFS setstripe -c -1 $DIR/$tdir
26750
26751         lru_resize_disable "" 100
26752         stack_trap "lru_resize_enable" EXIT
26753
26754         sleep 5
26755
26756         for i in $(seq $((MDSCOUNT * 125))); do
26757                 local t=$DIR/$tdir/$tfile_$i
26758
26759                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26760                         error_noexit "Create file $t"
26761         done
26762         stack_trap "rm -rf $DIR/$tdir" EXIT
26763
26764         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26765                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26766                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26767
26768                 [ $lock_count -le $lru_size ] ||
26769                         error "osc lock count $lock_count > lru size $lru_size"
26770         done
26771
26772         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26773                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26774                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26775
26776                 [ $lock_count -le $lru_size ] ||
26777                         error "mdc lock count $lock_count > lru size $lru_size"
26778         done
26779 }
26780 run_test 425 "lock count should not exceed lru size"
26781
26782 test_426() {
26783         splice-test -r $DIR/$tfile
26784         splice-test -rd $DIR/$tfile
26785         splice-test $DIR/$tfile
26786         splice-test -d $DIR/$tfile
26787 }
26788 run_test 426 "splice test on Lustre"
26789
26790 test_427() {
26791         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26792         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26793                 skip "Need MDS version at least 2.12.4"
26794         local log
26795
26796         mkdir $DIR/$tdir
26797         mkdir $DIR/$tdir/1
26798         mkdir $DIR/$tdir/2
26799         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26800         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26801
26802         $LFS getdirstripe $DIR/$tdir/1/dir
26803
26804         #first setfattr for creating updatelog
26805         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26806
26807 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26808         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26809         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26810         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26811
26812         sleep 2
26813         fail mds2
26814         wait_recovery_complete mds2 $((2*TIMEOUT))
26815
26816         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26817         echo $log | grep "get update log failed" &&
26818                 error "update log corruption is detected" || true
26819 }
26820 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26821
26822 test_428() {
26823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26824         local cache_limit=$CACHE_MAX
26825
26826         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26827         $LCTL set_param -n llite.*.max_cached_mb=64
26828
26829         mkdir $DIR/$tdir
26830         $LFS setstripe -c 1 $DIR/$tdir
26831         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26832         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26833         #test write
26834         for f in $(seq 4); do
26835                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26836         done
26837         wait
26838
26839         cancel_lru_locks osc
26840         # Test read
26841         for f in $(seq 4); do
26842                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26843         done
26844         wait
26845 }
26846 run_test 428 "large block size IO should not hang"
26847
26848 test_429() { # LU-7915 / LU-10948
26849         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26850         local testfile=$DIR/$tfile
26851         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26852         local new_flag=1
26853         local first_rpc
26854         local second_rpc
26855         local third_rpc
26856
26857         $LCTL get_param $ll_opencache_threshold_count ||
26858                 skip "client does not have opencache parameter"
26859
26860         set_opencache $new_flag
26861         stack_trap "restore_opencache"
26862         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26863                 error "enable opencache failed"
26864         touch $testfile
26865         # drop MDC DLM locks
26866         cancel_lru_locks mdc
26867         # clear MDC RPC stats counters
26868         $LCTL set_param $mdc_rpcstats=clear
26869
26870         # According to the current implementation, we need to run 3 times
26871         # open & close file to verify if opencache is enabled correctly.
26872         # 1st, RPCs are sent for lookup/open and open handle is released on
26873         #      close finally.
26874         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26875         #      so open handle won't be released thereafter.
26876         # 3rd, No RPC is sent out.
26877         $MULTIOP $testfile oc || error "multiop failed"
26878         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26879         echo "1st: $first_rpc RPCs in flight"
26880
26881         $MULTIOP $testfile oc || error "multiop failed"
26882         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26883         echo "2nd: $second_rpc RPCs in flight"
26884
26885         $MULTIOP $testfile oc || error "multiop failed"
26886         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26887         echo "3rd: $third_rpc RPCs in flight"
26888
26889         #verify no MDC RPC is sent
26890         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26891 }
26892 run_test 429 "verify if opencache flag on client side does work"
26893
26894 lseek_test_430() {
26895         local offset
26896         local file=$1
26897
26898         # data at [200K, 400K)
26899         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26900                 error "256K->512K dd fails"
26901         # data at [2M, 3M)
26902         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26903                 error "2M->3M dd fails"
26904         # data at [4M, 5M)
26905         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26906                 error "4M->5M dd fails"
26907         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26908         # start at first component hole #1
26909         printf "Seeking hole from 1000 ... "
26910         offset=$(lseek_test -l 1000 $file)
26911         echo $offset
26912         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26913         printf "Seeking data from 1000 ... "
26914         offset=$(lseek_test -d 1000 $file)
26915         echo $offset
26916         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26917
26918         # start at first component data block
26919         printf "Seeking hole from 300000 ... "
26920         offset=$(lseek_test -l 300000 $file)
26921         echo $offset
26922         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26923         printf "Seeking data from 300000 ... "
26924         offset=$(lseek_test -d 300000 $file)
26925         echo $offset
26926         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26927
26928         # start at the first component but beyond end of object size
26929         printf "Seeking hole from 1000000 ... "
26930         offset=$(lseek_test -l 1000000 $file)
26931         echo $offset
26932         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26933         printf "Seeking data from 1000000 ... "
26934         offset=$(lseek_test -d 1000000 $file)
26935         echo $offset
26936         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26937
26938         # start at second component stripe 2 (empty file)
26939         printf "Seeking hole from 1500000 ... "
26940         offset=$(lseek_test -l 1500000 $file)
26941         echo $offset
26942         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26943         printf "Seeking data from 1500000 ... "
26944         offset=$(lseek_test -d 1500000 $file)
26945         echo $offset
26946         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26947
26948         # start at second component stripe 1 (all data)
26949         printf "Seeking hole from 3000000 ... "
26950         offset=$(lseek_test -l 3000000 $file)
26951         echo $offset
26952         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26953         printf "Seeking data from 3000000 ... "
26954         offset=$(lseek_test -d 3000000 $file)
26955         echo $offset
26956         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26957
26958         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26959                 error "2nd dd fails"
26960         echo "Add data block at 640K...1280K"
26961
26962         # start at before new data block, in hole
26963         printf "Seeking hole from 600000 ... "
26964         offset=$(lseek_test -l 600000 $file)
26965         echo $offset
26966         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26967         printf "Seeking data from 600000 ... "
26968         offset=$(lseek_test -d 600000 $file)
26969         echo $offset
26970         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26971
26972         # start at the first component new data block
26973         printf "Seeking hole from 1000000 ... "
26974         offset=$(lseek_test -l 1000000 $file)
26975         echo $offset
26976         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26977         printf "Seeking data from 1000000 ... "
26978         offset=$(lseek_test -d 1000000 $file)
26979         echo $offset
26980         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26981
26982         # start at second component stripe 2, new data
26983         printf "Seeking hole from 1200000 ... "
26984         offset=$(lseek_test -l 1200000 $file)
26985         echo $offset
26986         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26987         printf "Seeking data from 1200000 ... "
26988         offset=$(lseek_test -d 1200000 $file)
26989         echo $offset
26990         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26991
26992         # start beyond file end
26993         printf "Using offset > filesize ... "
26994         lseek_test -l 4000000 $file && error "lseek should fail"
26995         printf "Using offset > filesize ... "
26996         lseek_test -d 4000000 $file && error "lseek should fail"
26997
26998         printf "Done\n\n"
26999 }
27000
27001 test_430a() {
27002         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27003                 skip "MDT does not support SEEK_HOLE"
27004
27005         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27006                 skip "OST does not support SEEK_HOLE"
27007
27008         local file=$DIR/$tdir/$tfile
27009
27010         mkdir -p $DIR/$tdir
27011
27012         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27013         # OST stripe #1 will have continuous data at [1M, 3M)
27014         # OST stripe #2 is empty
27015         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27016         lseek_test_430 $file
27017         rm $file
27018         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27019         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27020         lseek_test_430 $file
27021         rm $file
27022         $LFS setstripe -c2 -S 512K $file
27023         echo "Two stripes, stripe size 512K"
27024         lseek_test_430 $file
27025         rm $file
27026         # FLR with stale mirror
27027         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27028                        -N -c2 -S 1M $file
27029         echo "Mirrored file:"
27030         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27031         echo "Plain 2 stripes 1M"
27032         lseek_test_430 $file
27033         rm $file
27034 }
27035 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27036
27037 test_430b() {
27038         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27039                 skip "OST does not support SEEK_HOLE"
27040
27041         local offset
27042         local file=$DIR/$tdir/$tfile
27043
27044         mkdir -p $DIR/$tdir
27045         # Empty layout lseek should fail
27046         $MCREATE $file
27047         # seek from 0
27048         printf "Seeking hole from 0 ... "
27049         lseek_test -l 0 $file && error "lseek should fail"
27050         printf "Seeking data from 0 ... "
27051         lseek_test -d 0 $file && error "lseek should fail"
27052         rm $file
27053
27054         # 1M-hole file
27055         $LFS setstripe -E 1M -c2 -E eof $file
27056         $TRUNCATE $file 1048576
27057         printf "Seeking hole from 1000000 ... "
27058         offset=$(lseek_test -l 1000000 $file)
27059         echo $offset
27060         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27061         printf "Seeking data from 1000000 ... "
27062         lseek_test -d 1000000 $file && error "lseek should fail"
27063         rm $file
27064
27065         # full component followed by non-inited one
27066         $LFS setstripe -E 1M -c2 -E eof $file
27067         dd if=/dev/urandom of=$file bs=1M count=1
27068         printf "Seeking hole from 1000000 ... "
27069         offset=$(lseek_test -l 1000000 $file)
27070         echo $offset
27071         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27072         printf "Seeking hole from 1048576 ... "
27073         lseek_test -l 1048576 $file && error "lseek should fail"
27074         # init second component and truncate back
27075         echo "123" >> $file
27076         $TRUNCATE $file 1048576
27077         printf "Seeking hole from 1000000 ... "
27078         offset=$(lseek_test -l 1000000 $file)
27079         echo $offset
27080         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27081         printf "Seeking hole from 1048576 ... "
27082         lseek_test -l 1048576 $file && error "lseek should fail"
27083         # boundary checks for big values
27084         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27085         offset=$(lseek_test -d 0 $file.10g)
27086         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27087         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27088         offset=$(lseek_test -d 0 $file.100g)
27089         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27090         return 0
27091 }
27092 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27093
27094 test_430c() {
27095         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27096                 skip "OST does not support SEEK_HOLE"
27097
27098         local file=$DIR/$tdir/$tfile
27099         local start
27100
27101         mkdir -p $DIR/$tdir
27102         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27103
27104         # cp version 8.33+ prefers lseek over fiemap
27105         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27106                 start=$SECONDS
27107                 time cp $file /dev/null
27108                 (( SECONDS - start < 5 )) ||
27109                         error "cp: too long runtime $((SECONDS - start))"
27110
27111         fi
27112         # tar version 1.29+ supports SEEK_HOLE/DATA
27113         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27114                 start=$SECONDS
27115                 time tar cS $file - | cat > /dev/null
27116                 (( SECONDS - start < 5 )) ||
27117                         error "tar: too long runtime $((SECONDS - start))"
27118         fi
27119 }
27120 run_test 430c "lseek: external tools check"
27121
27122 test_431() { # LU-14187
27123         local file=$DIR/$tdir/$tfile
27124
27125         mkdir -p $DIR/$tdir
27126         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27127         dd if=/dev/urandom of=$file bs=4k count=1
27128         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27129         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27130         #define OBD_FAIL_OST_RESTART_IO 0x251
27131         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27132         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27133         cp $file $file.0
27134         cancel_lru_locks
27135         sync_all_data
27136         echo 3 > /proc/sys/vm/drop_caches
27137         diff  $file $file.0 || error "data diff"
27138 }
27139 run_test 431 "Restart transaction for IO"
27140
27141 cleanup_test_432() {
27142         do_facet mgs $LCTL nodemap_activate 0
27143         wait_nm_sync active
27144 }
27145
27146 test_432() {
27147         local tmpdir=$TMP/dir432
27148
27149         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27150                 skip "Need MDS version at least 2.14.52"
27151
27152         stack_trap cleanup_test_432 EXIT
27153         mkdir $DIR/$tdir
27154         mkdir $tmpdir
27155
27156         do_facet mgs $LCTL nodemap_activate 1
27157         wait_nm_sync active
27158         do_facet mgs $LCTL nodemap_modify --name default \
27159                 --property admin --value 1
27160         do_facet mgs $LCTL nodemap_modify --name default \
27161                 --property trusted --value 1
27162         cancel_lru_locks mdc
27163         wait_nm_sync default admin_nodemap
27164         wait_nm_sync default trusted_nodemap
27165
27166         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27167                grep -ci "Operation not permitted") -ne 0 ]; then
27168                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27169         fi
27170 }
27171 run_test 432 "mv dir from outside Lustre"
27172
27173 test_433() {
27174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27175
27176         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27177                 skip "inode cache not supported"
27178
27179         $LCTL set_param llite.*.inode_cache=0
27180         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27181
27182         local count=256
27183         local before
27184         local after
27185
27186         cancel_lru_locks mdc
27187         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27188         createmany -m $DIR/$tdir/f $count
27189         createmany -d $DIR/$tdir/d $count
27190         ls -l $DIR/$tdir > /dev/null
27191         stack_trap "rm -rf $DIR/$tdir"
27192
27193         before=$(num_objects)
27194         cancel_lru_locks mdc
27195         after=$(num_objects)
27196
27197         # sometimes even @before is less than 2 * count
27198         while (( before - after < count )); do
27199                 sleep 1
27200                 after=$(num_objects)
27201                 wait=$((wait + 1))
27202                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27203                 if (( wait > 60 )); then
27204                         error "inode slab grew from $before to $after"
27205                 fi
27206         done
27207
27208         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27209 }
27210 run_test 433 "ldlm lock cancel releases dentries and inodes"
27211
27212 prep_801() {
27213         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27214         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27215                 skip "Need server version at least 2.9.55"
27216
27217         start_full_debug_logging
27218 }
27219
27220 post_801() {
27221         stop_full_debug_logging
27222 }
27223
27224 barrier_stat() {
27225         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27226                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27227                            awk '/The barrier for/ { print $7 }')
27228                 echo $st
27229         else
27230                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27231                 echo \'$st\'
27232         fi
27233 }
27234
27235 barrier_expired() {
27236         local expired
27237
27238         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27239                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27240                           awk '/will be expired/ { print $7 }')
27241         else
27242                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27243         fi
27244
27245         echo $expired
27246 }
27247
27248 test_801a() {
27249         prep_801
27250
27251         echo "Start barrier_freeze at: $(date)"
27252         #define OBD_FAIL_BARRIER_DELAY          0x2202
27253         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27254         # Do not reduce barrier time - See LU-11873
27255         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27256
27257         sleep 2
27258         local b_status=$(barrier_stat)
27259         echo "Got barrier status at: $(date)"
27260         [ "$b_status" = "'freezing_p1'" ] ||
27261                 error "(1) unexpected barrier status $b_status"
27262
27263         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27264         wait
27265         b_status=$(barrier_stat)
27266         [ "$b_status" = "'frozen'" ] ||
27267                 error "(2) unexpected barrier status $b_status"
27268
27269         local expired=$(barrier_expired)
27270         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27271         sleep $((expired + 3))
27272
27273         b_status=$(barrier_stat)
27274         [ "$b_status" = "'expired'" ] ||
27275                 error "(3) unexpected barrier status $b_status"
27276
27277         # Do not reduce barrier time - See LU-11873
27278         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27279                 error "(4) fail to freeze barrier"
27280
27281         b_status=$(barrier_stat)
27282         [ "$b_status" = "'frozen'" ] ||
27283                 error "(5) unexpected barrier status $b_status"
27284
27285         echo "Start barrier_thaw at: $(date)"
27286         #define OBD_FAIL_BARRIER_DELAY          0x2202
27287         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27288         do_facet mgs $LCTL barrier_thaw $FSNAME &
27289
27290         sleep 2
27291         b_status=$(barrier_stat)
27292         echo "Got barrier status at: $(date)"
27293         [ "$b_status" = "'thawing'" ] ||
27294                 error "(6) unexpected barrier status $b_status"
27295
27296         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27297         wait
27298         b_status=$(barrier_stat)
27299         [ "$b_status" = "'thawed'" ] ||
27300                 error "(7) unexpected barrier status $b_status"
27301
27302         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27303         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27304         do_facet mgs $LCTL barrier_freeze $FSNAME
27305
27306         b_status=$(barrier_stat)
27307         [ "$b_status" = "'failed'" ] ||
27308                 error "(8) unexpected barrier status $b_status"
27309
27310         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27311         do_facet mgs $LCTL barrier_thaw $FSNAME
27312
27313         post_801
27314 }
27315 run_test 801a "write barrier user interfaces and stat machine"
27316
27317 test_801b() {
27318         prep_801
27319
27320         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27321         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27322         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27323         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27324         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27325
27326         cancel_lru_locks mdc
27327
27328         # 180 seconds should be long enough
27329         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27330
27331         local b_status=$(barrier_stat)
27332         [ "$b_status" = "'frozen'" ] ||
27333                 error "(6) unexpected barrier status $b_status"
27334
27335         mkdir $DIR/$tdir/d0/d10 &
27336         mkdir_pid=$!
27337
27338         touch $DIR/$tdir/d1/f13 &
27339         touch_pid=$!
27340
27341         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27342         ln_pid=$!
27343
27344         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27345         mv_pid=$!
27346
27347         rm -f $DIR/$tdir/d4/f12 &
27348         rm_pid=$!
27349
27350         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27351
27352         # To guarantee taht the 'stat' is not blocked
27353         b_status=$(barrier_stat)
27354         [ "$b_status" = "'frozen'" ] ||
27355                 error "(8) unexpected barrier status $b_status"
27356
27357         # let above commands to run at background
27358         sleep 5
27359
27360         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27361         ps -p $touch_pid || error "(10) touch should be blocked"
27362         ps -p $ln_pid || error "(11) link should be blocked"
27363         ps -p $mv_pid || error "(12) rename should be blocked"
27364         ps -p $rm_pid || error "(13) unlink should be blocked"
27365
27366         b_status=$(barrier_stat)
27367         [ "$b_status" = "'frozen'" ] ||
27368                 error "(14) unexpected barrier status $b_status"
27369
27370         do_facet mgs $LCTL barrier_thaw $FSNAME
27371         b_status=$(barrier_stat)
27372         [ "$b_status" = "'thawed'" ] ||
27373                 error "(15) unexpected barrier status $b_status"
27374
27375         wait $mkdir_pid || error "(16) mkdir should succeed"
27376         wait $touch_pid || error "(17) touch should succeed"
27377         wait $ln_pid || error "(18) link should succeed"
27378         wait $mv_pid || error "(19) rename should succeed"
27379         wait $rm_pid || error "(20) unlink should succeed"
27380
27381         post_801
27382 }
27383 run_test 801b "modification will be blocked by write barrier"
27384
27385 test_801c() {
27386         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27387
27388         prep_801
27389
27390         stop mds2 || error "(1) Fail to stop mds2"
27391
27392         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27393
27394         local b_status=$(barrier_stat)
27395         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27396                 do_facet mgs $LCTL barrier_thaw $FSNAME
27397                 error "(2) unexpected barrier status $b_status"
27398         }
27399
27400         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27401                 error "(3) Fail to rescan barrier bitmap"
27402
27403         # Do not reduce barrier time - See LU-11873
27404         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27405
27406         b_status=$(barrier_stat)
27407         [ "$b_status" = "'frozen'" ] ||
27408                 error "(4) unexpected barrier status $b_status"
27409
27410         do_facet mgs $LCTL barrier_thaw $FSNAME
27411         b_status=$(barrier_stat)
27412         [ "$b_status" = "'thawed'" ] ||
27413                 error "(5) unexpected barrier status $b_status"
27414
27415         local devname=$(mdsdevname 2)
27416
27417         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27418
27419         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27420                 error "(7) Fail to rescan barrier bitmap"
27421
27422         post_801
27423 }
27424 run_test 801c "rescan barrier bitmap"
27425
27426 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27427 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27428 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27429 saved_MOUNT_OPTS=$MOUNT_OPTS
27430
27431 cleanup_802a() {
27432         trap 0
27433
27434         stopall
27435         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27436         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27437         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27438         MOUNT_OPTS=$saved_MOUNT_OPTS
27439         setupall
27440 }
27441
27442 test_802a() {
27443         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27444         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27445         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27446                 skip "Need server version at least 2.9.55"
27447
27448         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27449
27450         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27451
27452         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27453                 error "(2) Fail to copy"
27454
27455         trap cleanup_802a EXIT
27456
27457         # sync by force before remount as readonly
27458         sync; sync_all_data; sleep 3; sync_all_data
27459
27460         stopall
27461
27462         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27463         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27464         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27465
27466         echo "Mount the server as read only"
27467         setupall server_only || error "(3) Fail to start servers"
27468
27469         echo "Mount client without ro should fail"
27470         mount_client $MOUNT &&
27471                 error "(4) Mount client without 'ro' should fail"
27472
27473         echo "Mount client with ro should succeed"
27474         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27475         mount_client $MOUNT ||
27476                 error "(5) Mount client with 'ro' should succeed"
27477
27478         echo "Modify should be refused"
27479         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27480
27481         echo "Read should be allowed"
27482         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27483                 error "(7) Read should succeed under ro mode"
27484
27485         cleanup_802a
27486 }
27487 run_test 802a "simulate readonly device"
27488
27489 test_802b() {
27490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27491         remote_mds_nodsh && skip "remote MDS with nodsh"
27492
27493         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27494                 skip "readonly option not available"
27495
27496         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27497
27498         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27499                 error "(2) Fail to copy"
27500
27501         # write back all cached data before setting MDT to readonly
27502         cancel_lru_locks
27503         sync_all_data
27504
27505         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27506         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27507
27508         echo "Modify should be refused"
27509         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27510
27511         echo "Read should be allowed"
27512         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27513                 error "(7) Read should succeed under ro mode"
27514
27515         # disable readonly
27516         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27517 }
27518 run_test 802b "be able to set MDTs to readonly"
27519
27520 test_803a() {
27521         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27522         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27523                 skip "MDS needs to be newer than 2.10.54"
27524
27525         mkdir_on_mdt0 $DIR/$tdir
27526         # Create some objects on all MDTs to trigger related logs objects
27527         for idx in $(seq $MDSCOUNT); do
27528                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27529                         $DIR/$tdir/dir${idx} ||
27530                         error "Fail to create $DIR/$tdir/dir${idx}"
27531         done
27532
27533         sync; sleep 3
27534         wait_delete_completed # ensure old test cleanups are finished
27535         echo "before create:"
27536         $LFS df -i $MOUNT
27537         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27538
27539         for i in {1..10}; do
27540                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27541                         error "Fail to create $DIR/$tdir/foo$i"
27542         done
27543
27544         sync; sleep 3
27545         echo "after create:"
27546         $LFS df -i $MOUNT
27547         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27548
27549         # allow for an llog to be cleaned up during the test
27550         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27551                 error "before ($before_used) + 10 > after ($after_used)"
27552
27553         for i in {1..10}; do
27554                 rm -rf $DIR/$tdir/foo$i ||
27555                         error "Fail to remove $DIR/$tdir/foo$i"
27556         done
27557
27558         sleep 3 # avoid MDT return cached statfs
27559         wait_delete_completed
27560         echo "after unlink:"
27561         $LFS df -i $MOUNT
27562         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27563
27564         # allow for an llog to be created during the test
27565         [ $after_used -le $((before_used + 1)) ] ||
27566                 error "after ($after_used) > before ($before_used) + 1"
27567 }
27568 run_test 803a "verify agent object for remote object"
27569
27570 test_803b() {
27571         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27572         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27573                 skip "MDS needs to be newer than 2.13.56"
27574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27575
27576         for i in $(seq 0 $((MDSCOUNT - 1))); do
27577                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27578         done
27579
27580         local before=0
27581         local after=0
27582
27583         local tmp
27584
27585         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27586         for i in $(seq 0 $((MDSCOUNT - 1))); do
27587                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27588                         awk '/getattr/ { print $2 }')
27589                 before=$((before + tmp))
27590         done
27591         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27592         for i in $(seq 0 $((MDSCOUNT - 1))); do
27593                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27594                         awk '/getattr/ { print $2 }')
27595                 after=$((after + tmp))
27596         done
27597
27598         [ $before -eq $after ] || error "getattr count $before != $after"
27599 }
27600 run_test 803b "remote object can getattr from cache"
27601
27602 test_804() {
27603         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27604         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27605                 skip "MDS needs to be newer than 2.10.54"
27606         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27607
27608         mkdir -p $DIR/$tdir
27609         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27610                 error "Fail to create $DIR/$tdir/dir0"
27611
27612         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27613         local dev=$(mdsdevname 2)
27614
27615         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27616                 grep ${fid} || error "NOT found agent entry for dir0"
27617
27618         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27619                 error "Fail to create $DIR/$tdir/dir1"
27620
27621         touch $DIR/$tdir/dir1/foo0 ||
27622                 error "Fail to create $DIR/$tdir/dir1/foo0"
27623         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27624         local rc=0
27625
27626         for idx in $(seq $MDSCOUNT); do
27627                 dev=$(mdsdevname $idx)
27628                 do_facet mds${idx} \
27629                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27630                         grep ${fid} && rc=$idx
27631         done
27632
27633         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27634                 error "Fail to rename foo0 to foo1"
27635         if [ $rc -eq 0 ]; then
27636                 for idx in $(seq $MDSCOUNT); do
27637                         dev=$(mdsdevname $idx)
27638                         do_facet mds${idx} \
27639                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27640                         grep ${fid} && rc=$idx
27641                 done
27642         fi
27643
27644         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27645                 error "Fail to rename foo1 to foo2"
27646         if [ $rc -eq 0 ]; then
27647                 for idx in $(seq $MDSCOUNT); do
27648                         dev=$(mdsdevname $idx)
27649                         do_facet mds${idx} \
27650                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27651                         grep ${fid} && rc=$idx
27652                 done
27653         fi
27654
27655         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27656
27657         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27658                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27659         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27660                 error "Fail to rename foo2 to foo0"
27661         unlink $DIR/$tdir/dir1/foo0 ||
27662                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27663         rm -rf $DIR/$tdir/dir0 ||
27664                 error "Fail to rm $DIR/$tdir/dir0"
27665
27666         for idx in $(seq $MDSCOUNT); do
27667                 rc=0
27668
27669                 stop mds${idx}
27670                 dev=$(mdsdevname $idx)
27671                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27672                         rc=$?
27673                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27674                         error "mount mds$idx failed"
27675                 df $MOUNT > /dev/null 2>&1
27676
27677                 # e2fsck should not return error
27678                 [ $rc -eq 0 ] ||
27679                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27680         done
27681 }
27682 run_test 804 "verify agent entry for remote entry"
27683
27684 cleanup_805() {
27685         do_facet $SINGLEMDS zfs set quota=$old $fsset
27686         unlinkmany $DIR/$tdir/f- 1000000
27687         trap 0
27688 }
27689
27690 test_805() {
27691         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27692         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27693         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27694                 skip "netfree not implemented before 0.7"
27695         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27696                 skip "Need MDS version at least 2.10.57"
27697
27698         local fsset
27699         local freekb
27700         local usedkb
27701         local old
27702         local quota
27703         local pref="osd-zfs.$FSNAME-MDT0000."
27704
27705         # limit available space on MDS dataset to meet nospace issue
27706         # quickly. then ZFS 0.7.2 can use reserved space if asked
27707         # properly (using netfree flag in osd_declare_destroy()
27708         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27709         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27710                 gawk '{print $3}')
27711         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27712         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27713         let "usedkb=usedkb-freekb"
27714         let "freekb=freekb/2"
27715         if let "freekb > 5000"; then
27716                 let "freekb=5000"
27717         fi
27718         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27719         trap cleanup_805 EXIT
27720         mkdir_on_mdt0 $DIR/$tdir
27721         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27722                 error "Can't set PFL layout"
27723         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27724         rm -rf $DIR/$tdir || error "not able to remove"
27725         do_facet $SINGLEMDS zfs set quota=$old $fsset
27726         trap 0
27727 }
27728 run_test 805 "ZFS can remove from full fs"
27729
27730 # Size-on-MDS test
27731 check_lsom_data()
27732 {
27733         local file=$1
27734         local expect=$(stat -c %s $file)
27735
27736         check_lsom_size $1 $expect
27737
27738         local blocks=$($LFS getsom -b $file)
27739         expect=$(stat -c %b $file)
27740         [[ $blocks == $expect ]] ||
27741                 error "$file expected blocks: $expect, got: $blocks"
27742 }
27743
27744 check_lsom_size()
27745 {
27746         local size
27747         local expect=$2
27748
27749         cancel_lru_locks mdc
27750
27751         size=$($LFS getsom -s $1)
27752         [[ $size == $expect ]] ||
27753                 error "$file expected size: $expect, got: $size"
27754 }
27755
27756 test_806() {
27757         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27758                 skip "Need MDS version at least 2.11.52"
27759
27760         local bs=1048576
27761
27762         touch $DIR/$tfile || error "touch $tfile failed"
27763
27764         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27765         save_lustre_params client "llite.*.xattr_cache" > $save
27766         lctl set_param llite.*.xattr_cache=0
27767         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27768
27769         # single-threaded write
27770         echo "Test SOM for single-threaded write"
27771         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27772                 error "write $tfile failed"
27773         check_lsom_size $DIR/$tfile $bs
27774
27775         local num=32
27776         local size=$(($num * $bs))
27777         local offset=0
27778         local i
27779
27780         echo "Test SOM for single client multi-threaded($num) write"
27781         $TRUNCATE $DIR/$tfile 0
27782         for ((i = 0; i < $num; i++)); do
27783                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27784                 local pids[$i]=$!
27785                 offset=$((offset + $bs))
27786         done
27787         for (( i=0; i < $num; i++ )); do
27788                 wait ${pids[$i]}
27789         done
27790         check_lsom_size $DIR/$tfile $size
27791
27792         $TRUNCATE $DIR/$tfile 0
27793         for ((i = 0; i < $num; i++)); do
27794                 offset=$((offset - $bs))
27795                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27796                 local pids[$i]=$!
27797         done
27798         for (( i=0; i < $num; i++ )); do
27799                 wait ${pids[$i]}
27800         done
27801         check_lsom_size $DIR/$tfile $size
27802
27803         # multi-client writes
27804         num=$(get_node_count ${CLIENTS//,/ })
27805         size=$(($num * $bs))
27806         offset=0
27807         i=0
27808
27809         echo "Test SOM for multi-client ($num) writes"
27810         $TRUNCATE $DIR/$tfile 0
27811         for client in ${CLIENTS//,/ }; do
27812                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27813                 local pids[$i]=$!
27814                 i=$((i + 1))
27815                 offset=$((offset + $bs))
27816         done
27817         for (( i=0; i < $num; i++ )); do
27818                 wait ${pids[$i]}
27819         done
27820         check_lsom_size $DIR/$tfile $offset
27821
27822         i=0
27823         $TRUNCATE $DIR/$tfile 0
27824         for client in ${CLIENTS//,/ }; do
27825                 offset=$((offset - $bs))
27826                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27827                 local pids[$i]=$!
27828                 i=$((i + 1))
27829         done
27830         for (( i=0; i < $num; i++ )); do
27831                 wait ${pids[$i]}
27832         done
27833         check_lsom_size $DIR/$tfile $size
27834
27835         # verify truncate
27836         echo "Test SOM for truncate"
27837         $TRUNCATE $DIR/$tfile 1048576
27838         check_lsom_size $DIR/$tfile 1048576
27839         $TRUNCATE $DIR/$tfile 1234
27840         check_lsom_size $DIR/$tfile 1234
27841
27842         # verify SOM blocks count
27843         echo "Verify SOM block count"
27844         $TRUNCATE $DIR/$tfile 0
27845         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27846                 error "failed to write file $tfile"
27847         check_lsom_data $DIR/$tfile
27848 }
27849 run_test 806 "Verify Lazy Size on MDS"
27850
27851 test_807() {
27852         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27853         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27854                 skip "Need MDS version at least 2.11.52"
27855
27856         # Registration step
27857         changelog_register || error "changelog_register failed"
27858         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27859         changelog_users $SINGLEMDS | grep -q $cl_user ||
27860                 error "User $cl_user not found in changelog_users"
27861
27862         rm -rf $DIR/$tdir || error "rm $tdir failed"
27863         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27864         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27865         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27866         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27867                 error "truncate $tdir/trunc failed"
27868
27869         local bs=1048576
27870         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27871                 error "write $tfile failed"
27872
27873         # multi-client wirtes
27874         local num=$(get_node_count ${CLIENTS//,/ })
27875         local offset=0
27876         local i=0
27877
27878         echo "Test SOM for multi-client ($num) writes"
27879         touch $DIR/$tfile || error "touch $tfile failed"
27880         $TRUNCATE $DIR/$tfile 0
27881         for client in ${CLIENTS//,/ }; do
27882                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27883                 local pids[$i]=$!
27884                 i=$((i + 1))
27885                 offset=$((offset + $bs))
27886         done
27887         for (( i=0; i < $num; i++ )); do
27888                 wait ${pids[$i]}
27889         done
27890
27891         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27892         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27893         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27894         check_lsom_data $DIR/$tdir/trunc
27895         check_lsom_data $DIR/$tdir/single_dd
27896         check_lsom_data $DIR/$tfile
27897
27898         rm -rf $DIR/$tdir
27899         # Deregistration step
27900         changelog_deregister || error "changelog_deregister failed"
27901 }
27902 run_test 807 "verify LSOM syncing tool"
27903
27904 check_som_nologged()
27905 {
27906         local lines=$($LFS changelog $FSNAME-MDT0000 |
27907                 grep 'x=trusted.som' | wc -l)
27908         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27909 }
27910
27911 test_808() {
27912         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27913                 skip "Need MDS version at least 2.11.55"
27914
27915         # Registration step
27916         changelog_register || error "changelog_register failed"
27917
27918         touch $DIR/$tfile || error "touch $tfile failed"
27919         check_som_nologged
27920
27921         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27922                 error "write $tfile failed"
27923         check_som_nologged
27924
27925         $TRUNCATE $DIR/$tfile 1234
27926         check_som_nologged
27927
27928         $TRUNCATE $DIR/$tfile 1048576
27929         check_som_nologged
27930
27931         # Deregistration step
27932         changelog_deregister || error "changelog_deregister failed"
27933 }
27934 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27935
27936 check_som_nodata()
27937 {
27938         $LFS getsom $1
27939         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27940 }
27941
27942 test_809() {
27943         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27944                 skip "Need MDS version at least 2.11.56"
27945
27946         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27947                 error "failed to create DoM-only file $DIR/$tfile"
27948         touch $DIR/$tfile || error "touch $tfile failed"
27949         check_som_nodata $DIR/$tfile
27950
27951         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27952                 error "write $tfile failed"
27953         check_som_nodata $DIR/$tfile
27954
27955         $TRUNCATE $DIR/$tfile 1234
27956         check_som_nodata $DIR/$tfile
27957
27958         $TRUNCATE $DIR/$tfile 4097
27959         check_som_nodata $DIR/$file
27960 }
27961 run_test 809 "Verify no SOM xattr store for DoM-only files"
27962
27963 test_810() {
27964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27965         $GSS && skip_env "could not run with gss"
27966         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27967                 skip "OST < 2.12.58 doesn't align checksum"
27968
27969         set_checksums 1
27970         stack_trap "set_checksums $ORIG_CSUM" EXIT
27971         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27972
27973         local csum
27974         local before
27975         local after
27976         for csum in $CKSUM_TYPES; do
27977                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27978                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27979                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27980                         eval set -- $i
27981                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27982                         before=$(md5sum $DIR/$tfile)
27983                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27984                         after=$(md5sum $DIR/$tfile)
27985                         [ "$before" == "$after" ] ||
27986                                 error "$csum: $before != $after bs=$1 seek=$2"
27987                 done
27988         done
27989 }
27990 run_test 810 "partial page writes on ZFS (LU-11663)"
27991
27992 test_812a() {
27993         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27994                 skip "OST < 2.12.51 doesn't support this fail_loc"
27995
27996         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27997         # ensure ost1 is connected
27998         stat $DIR/$tfile >/dev/null || error "can't stat"
27999         wait_osc_import_state client ost1 FULL
28000         # no locks, no reqs to let the connection idle
28001         cancel_lru_locks osc
28002
28003         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28004 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28005         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28006         wait_osc_import_state client ost1 CONNECTING
28007         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28008
28009         stat $DIR/$tfile >/dev/null || error "can't stat file"
28010 }
28011 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28012
28013 test_812b() { # LU-12378
28014         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28015                 skip "OST < 2.12.51 doesn't support this fail_loc"
28016
28017         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28018         # ensure ost1 is connected
28019         stat $DIR/$tfile >/dev/null || error "can't stat"
28020         wait_osc_import_state client ost1 FULL
28021         # no locks, no reqs to let the connection idle
28022         cancel_lru_locks osc
28023
28024         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28025 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28026         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28027         wait_osc_import_state client ost1 CONNECTING
28028         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28029
28030         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28031         wait_osc_import_state client ost1 IDLE
28032 }
28033 run_test 812b "do not drop no resend request for idle connect"
28034
28035 test_812c() {
28036         local old
28037
28038         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28039
28040         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28041         $LFS getstripe $DIR/$tfile
28042         $LCTL set_param osc.*.idle_timeout=10
28043         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28044         # ensure ost1 is connected
28045         stat $DIR/$tfile >/dev/null || error "can't stat"
28046         wait_osc_import_state client ost1 FULL
28047         # no locks, no reqs to let the connection idle
28048         cancel_lru_locks osc
28049
28050 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28051         $LCTL set_param fail_loc=0x80000533
28052         sleep 15
28053         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28054 }
28055 run_test 812c "idle import vs lock enqueue race"
28056
28057 test_813() {
28058         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28059         [ -z "$file_heat_sav" ] && skip "no file heat support"
28060
28061         local readsample
28062         local writesample
28063         local readbyte
28064         local writebyte
28065         local readsample1
28066         local writesample1
28067         local readbyte1
28068         local writebyte1
28069
28070         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28071         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28072
28073         $LCTL set_param -n llite.*.file_heat=1
28074         echo "Turn on file heat"
28075         echo "Period second: $period_second, Decay percentage: $decay_pct"
28076
28077         echo "QQQQ" > $DIR/$tfile
28078         echo "QQQQ" > $DIR/$tfile
28079         echo "QQQQ" > $DIR/$tfile
28080         cat $DIR/$tfile > /dev/null
28081         cat $DIR/$tfile > /dev/null
28082         cat $DIR/$tfile > /dev/null
28083         cat $DIR/$tfile > /dev/null
28084
28085         local out=$($LFS heat_get $DIR/$tfile)
28086
28087         $LFS heat_get $DIR/$tfile
28088         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28089         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28090         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28091         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28092
28093         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28094         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28095         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28096         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28097
28098         sleep $((period_second + 3))
28099         echo "Sleep $((period_second + 3)) seconds..."
28100         # The recursion formula to calculate the heat of the file f is as
28101         # follow:
28102         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28103         # Where Hi is the heat value in the period between time points i*I and
28104         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28105         # to the weight of Ci.
28106         out=$($LFS heat_get $DIR/$tfile)
28107         $LFS heat_get $DIR/$tfile
28108         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28109         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28110         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28111         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28112
28113         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28114                 error "read sample ($readsample) is wrong"
28115         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28116                 error "write sample ($writesample) is wrong"
28117         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28118                 error "read bytes ($readbyte) is wrong"
28119         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28120                 error "write bytes ($writebyte) is wrong"
28121
28122         echo "QQQQ" > $DIR/$tfile
28123         echo "QQQQ" > $DIR/$tfile
28124         echo "QQQQ" > $DIR/$tfile
28125         cat $DIR/$tfile > /dev/null
28126         cat $DIR/$tfile > /dev/null
28127         cat $DIR/$tfile > /dev/null
28128         cat $DIR/$tfile > /dev/null
28129
28130         sleep $((period_second + 3))
28131         echo "Sleep $((period_second + 3)) seconds..."
28132
28133         out=$($LFS heat_get $DIR/$tfile)
28134         $LFS heat_get $DIR/$tfile
28135         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28136         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28137         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28138         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28139
28140         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28141                 4 * $decay_pct) / 100") -eq 1 ] ||
28142                 error "read sample ($readsample1) is wrong"
28143         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28144                 3 * $decay_pct) / 100") -eq 1 ] ||
28145                 error "write sample ($writesample1) is wrong"
28146         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28147                 20 * $decay_pct) / 100") -eq 1 ] ||
28148                 error "read bytes ($readbyte1) is wrong"
28149         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28150                 15 * $decay_pct) / 100") -eq 1 ] ||
28151                 error "write bytes ($writebyte1) is wrong"
28152
28153         echo "Turn off file heat for the file $DIR/$tfile"
28154         $LFS heat_set -o $DIR/$tfile
28155
28156         echo "QQQQ" > $DIR/$tfile
28157         echo "QQQQ" > $DIR/$tfile
28158         echo "QQQQ" > $DIR/$tfile
28159         cat $DIR/$tfile > /dev/null
28160         cat $DIR/$tfile > /dev/null
28161         cat $DIR/$tfile > /dev/null
28162         cat $DIR/$tfile > /dev/null
28163
28164         out=$($LFS heat_get $DIR/$tfile)
28165         $LFS heat_get $DIR/$tfile
28166         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28167         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28168         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28169         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28170
28171         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28172         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28173         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28174         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28175
28176         echo "Trun on file heat for the file $DIR/$tfile"
28177         $LFS heat_set -O $DIR/$tfile
28178
28179         echo "QQQQ" > $DIR/$tfile
28180         echo "QQQQ" > $DIR/$tfile
28181         echo "QQQQ" > $DIR/$tfile
28182         cat $DIR/$tfile > /dev/null
28183         cat $DIR/$tfile > /dev/null
28184         cat $DIR/$tfile > /dev/null
28185         cat $DIR/$tfile > /dev/null
28186
28187         out=$($LFS heat_get $DIR/$tfile)
28188         $LFS heat_get $DIR/$tfile
28189         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28190         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28191         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28192         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28193
28194         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28195         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28196         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28197         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28198
28199         $LFS heat_set -c $DIR/$tfile
28200         $LCTL set_param -n llite.*.file_heat=0
28201         echo "Turn off file heat support for the Lustre filesystem"
28202
28203         echo "QQQQ" > $DIR/$tfile
28204         echo "QQQQ" > $DIR/$tfile
28205         echo "QQQQ" > $DIR/$tfile
28206         cat $DIR/$tfile > /dev/null
28207         cat $DIR/$tfile > /dev/null
28208         cat $DIR/$tfile > /dev/null
28209         cat $DIR/$tfile > /dev/null
28210
28211         out=$($LFS heat_get $DIR/$tfile)
28212         $LFS heat_get $DIR/$tfile
28213         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28214         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28215         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28216         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28217
28218         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28219         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28220         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28221         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28222
28223         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28224         rm -f $DIR/$tfile
28225 }
28226 run_test 813 "File heat verfication"
28227
28228 test_814()
28229 {
28230         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28231         echo -n y >> $DIR/$tfile
28232         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28233         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28234 }
28235 run_test 814 "sparse cp works as expected (LU-12361)"
28236
28237 test_815()
28238 {
28239         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28240         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28241 }
28242 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28243
28244 test_816() {
28245         local ost1_imp=$(get_osc_import_name client ost1)
28246         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28247                          cut -d'.' -f2)
28248
28249         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28250         # ensure ost1 is connected
28251
28252         stat $DIR/$tfile >/dev/null || error "can't stat"
28253         wait_osc_import_state client ost1 FULL
28254         # no locks, no reqs to let the connection idle
28255         cancel_lru_locks osc
28256         lru_resize_disable osc
28257         local before
28258         local now
28259         before=$($LCTL get_param -n \
28260                  ldlm.namespaces.$imp_name.lru_size)
28261
28262         wait_osc_import_state client ost1 IDLE
28263         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28264         now=$($LCTL get_param -n \
28265               ldlm.namespaces.$imp_name.lru_size)
28266         [ $before == $now ] || error "lru_size changed $before != $now"
28267 }
28268 run_test 816 "do not reset lru_resize on idle reconnect"
28269
28270 cleanup_817() {
28271         umount $tmpdir
28272         exportfs -u localhost:$DIR/nfsexp
28273         rm -rf $DIR/nfsexp
28274 }
28275
28276 test_817() {
28277         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28278
28279         mkdir -p $DIR/nfsexp
28280         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28281                 error "failed to export nfs"
28282
28283         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28284         stack_trap cleanup_817 EXIT
28285
28286         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28287                 error "failed to mount nfs to $tmpdir"
28288
28289         cp /bin/true $tmpdir
28290         $DIR/nfsexp/true || error "failed to execute 'true' command"
28291 }
28292 run_test 817 "nfsd won't cache write lock for exec file"
28293
28294 test_818() {
28295         test_mkdir -i0 -c1 $DIR/$tdir
28296         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28297         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28298         stop $SINGLEMDS
28299
28300         # restore osp-syn threads
28301         stack_trap "fail $SINGLEMDS"
28302
28303         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28304         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28305         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28306                 error "start $SINGLEMDS failed"
28307         rm -rf $DIR/$tdir
28308
28309         local testid=$(echo $TESTNAME | tr '_' ' ')
28310
28311         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28312                 grep "run LFSCK" || error "run LFSCK is not suggested"
28313 }
28314 run_test 818 "unlink with failed llog"
28315
28316 test_819a() {
28317         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28318         cancel_lru_locks osc
28319         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28320         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28321         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28322         rm -f $TDIR/$tfile
28323 }
28324 run_test 819a "too big niobuf in read"
28325
28326 test_819b() {
28327         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28328         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28329         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28330         cancel_lru_locks osc
28331         sleep 1
28332         rm -f $TDIR/$tfile
28333 }
28334 run_test 819b "too big niobuf in write"
28335
28336
28337 function test_820_start_ost() {
28338         sleep 5
28339
28340         for num in $(seq $OSTCOUNT); do
28341                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28342         done
28343 }
28344
28345 test_820() {
28346         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28347
28348         mkdir $DIR/$tdir
28349         umount_client $MOUNT || error "umount failed"
28350         for num in $(seq $OSTCOUNT); do
28351                 stop ost$num
28352         done
28353
28354         # mount client with no active OSTs
28355         # so that the client can't initialize max LOV EA size
28356         # from OSC notifications
28357         mount_client $MOUNT || error "mount failed"
28358         # delay OST starting to keep this 0 max EA size for a while
28359         test_820_start_ost &
28360
28361         # create a directory on MDS2
28362         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28363                 error "Failed to create directory"
28364         # open intent should update default EA size
28365         # see mdc_update_max_ea_from_body()
28366         # notice this is the very first RPC to MDS2
28367         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28368         ret=$?
28369         echo $out
28370         # With SSK, this situation can lead to -EPERM being returned.
28371         # In that case, simply retry.
28372         if [ $ret -ne 0 ] && $SHARED_KEY; then
28373                 if echo "$out" | grep -q "not permitted"; then
28374                         cp /etc/services $DIR/$tdir/mds2
28375                         ret=$?
28376                 fi
28377         fi
28378         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28379 }
28380 run_test 820 "update max EA from open intent"
28381
28382 test_823() {
28383         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28384         local OST_MAX_PRECREATE=20000
28385
28386         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28387                 skip "Need MDS version at least 2.14.56"
28388
28389         save_lustre_params mds1 \
28390                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28391         do_facet $SINGLEMDS "$LCTL set_param -n \
28392                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28393         do_facet $SINGLEMDS "$LCTL set_param -n \
28394                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28395
28396         stack_trap "restore_lustre_params < $p; rm $p"
28397
28398         do_facet $SINGLEMDS "$LCTL set_param -n \
28399                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28400
28401         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28402                       osp.$FSNAME-OST0000*MDT0000.create_count")
28403         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28404                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28405         local expect_count=$(((($max/2)/256) * 256))
28406
28407         log "setting create_count to 100200:"
28408         log " -result- count: $count with max: $max, expecting: $expect_count"
28409
28410         [[ $count -eq expect_count ]] ||
28411                 error "Create count not set to max precreate."
28412 }
28413 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28414
28415 test_831() {
28416         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28417                 skip "Need MDS version 2.14.56"
28418
28419         local sync_changes=$(do_facet $SINGLEMDS \
28420                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28421
28422         [ "$sync_changes" -gt 100 ] &&
28423                 skip "Sync changes $sync_changes > 100 already"
28424
28425         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28426
28427         $LFS mkdir -i 0 $DIR/$tdir
28428         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28429
28430         save_lustre_params mds1 \
28431                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28432         save_lustre_params mds1 \
28433                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28434
28435         do_facet mds1 "$LCTL set_param -n \
28436                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28437                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28438         stack_trap "restore_lustre_params < $p" EXIT
28439
28440         createmany -o $DIR/$tdir/f- 1000
28441         unlinkmany $DIR/$tdir/f- 1000 &
28442         local UNLINK_PID=$!
28443
28444         while sleep 1; do
28445                 sync_changes=$(do_facet mds1 \
28446                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28447                 # the check in the code is racy, fail the test
28448                 # if the value above the limit by 10.
28449                 [ $sync_changes -gt 110 ] && {
28450                         kill -2 $UNLINK_PID
28451                         wait
28452                         error "osp changes throttling failed, $sync_changes>110"
28453                 }
28454                 kill -0 $UNLINK_PID 2> /dev/null || break
28455         done
28456         wait
28457 }
28458 run_test 831 "throttling unlink/setattr queuing on OSP"
28459
28460 #
28461 # tests that do cleanup/setup should be run at the end
28462 #
28463
28464 test_900() {
28465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28466         local ls
28467
28468         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28469         $LCTL set_param fail_loc=0x903
28470
28471         cancel_lru_locks MGC
28472
28473         FAIL_ON_ERROR=true cleanup
28474         FAIL_ON_ERROR=true setup
28475 }
28476 run_test 900 "umount should not race with any mgc requeue thread"
28477
28478 # LUS-6253/LU-11185
28479 test_901() {
28480         local old
28481         local count
28482         local oldc
28483         local newc
28484         local olds
28485         local news
28486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28487
28488         # some get_param have a bug to handle dot in param name
28489         cancel_lru_locks MGC
28490         old=$(mount -t lustre | wc -l)
28491         # 1 config+sptlrpc
28492         # 2 params
28493         # 3 nodemap
28494         # 4 IR
28495         old=$((old * 4))
28496         oldc=0
28497         count=0
28498         while [ $old -ne $oldc ]; do
28499                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28500                 sleep 1
28501                 ((count++))
28502                 if [ $count -ge $TIMEOUT ]; then
28503                         error "too large timeout"
28504                 fi
28505         done
28506         umount_client $MOUNT || error "umount failed"
28507         mount_client $MOUNT || error "mount failed"
28508         cancel_lru_locks MGC
28509         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28510
28511         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28512
28513         return 0
28514 }
28515 run_test 901 "don't leak a mgc lock on client umount"
28516
28517 # LU-13377
28518 test_902() {
28519         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28520                 skip "client does not have LU-13377 fix"
28521         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28522         $LCTL set_param fail_loc=0x1415
28523         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28524         cancel_lru_locks osc
28525         rm -f $DIR/$tfile
28526 }
28527 run_test 902 "test short write doesn't hang lustre"
28528
28529 # LU-14711
28530 test_903() {
28531         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28532         echo "blah" > $DIR/${tfile}-2
28533         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28534         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28535         $LCTL set_param fail_loc=0x417 fail_val=20
28536
28537         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28538         sleep 1 # To start the destroy
28539         wait_destroy_complete 150 || error "Destroy taking too long"
28540         cat $DIR/$tfile > /dev/null || error "Evicted"
28541 }
28542 run_test 903 "Test long page discard does not cause evictions"
28543
28544 test_904() {
28545         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28546         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28547                 grep -q project || skip "skip project quota not supported"
28548
28549         local testfile="$DIR/$tdir/$tfile"
28550         local xattr="trusted.projid"
28551         local projid
28552         local mdts=$(comma_list $(mdts_nodes))
28553         local saved=$(do_facet mds1 $LCTL get_param -n \
28554                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28555
28556         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28557         stack_trap "do_nodes $mdts $LCTL set_param \
28558                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28559
28560         mkdir -p $DIR/$tdir
28561         touch $testfile
28562         #hide projid xattr on server
28563         $LFS project -p 1 $testfile ||
28564                 error "set $testfile project id failed"
28565         getfattr -m - $testfile | grep $xattr &&
28566                 error "do not show trusted.projid when disabled on server"
28567         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28568         #should be hidden when projid is 0
28569         $LFS project -p 0 $testfile ||
28570                 error "set $testfile project id failed"
28571         getfattr -m - $testfile | grep $xattr &&
28572                 error "do not show trusted.projid with project ID 0"
28573
28574         #still can getxattr explicitly
28575         projid=$(getfattr -n $xattr $testfile |
28576                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28577         [ $projid == "0" ] ||
28578                 error "projid expected 0 not $projid"
28579
28580         #set the projid via setxattr
28581         setfattr -n $xattr -v "1000" $testfile ||
28582                 error "setattr failed with $?"
28583         projid=($($LFS project $testfile))
28584         [ ${projid[0]} == "1000" ] ||
28585                 error "projid expected 1000 not $projid"
28586
28587         #check the new projid via getxattr
28588         $LFS project -p 1001 $testfile ||
28589                 error "set $testfile project id failed"
28590         getfattr -m - $testfile | grep $xattr ||
28591                 error "should show trusted.projid when project ID != 0"
28592         projid=$(getfattr -n $xattr $testfile |
28593                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28594         [ $projid == "1001" ] ||
28595                 error "projid expected 1001 not $projid"
28596
28597         #try to set invalid projid
28598         setfattr -n $xattr -v "4294967295" $testfile &&
28599                 error "set invalid projid should fail"
28600
28601         #remove the xattr means setting projid to 0
28602         setfattr -x $xattr $testfile ||
28603                 error "setfattr failed with $?"
28604         projid=($($LFS project $testfile))
28605         [ ${projid[0]} == "0" ] ||
28606                 error "projid expected 0 not $projid"
28607
28608         #should be hidden when parent has inherit flag and same projid
28609         $LFS project -srp 1002 $DIR/$tdir ||
28610                 error "set $tdir project id failed"
28611         getfattr -m - $testfile | grep $xattr &&
28612                 error "do not show trusted.projid with inherit flag"
28613
28614         #still can getxattr explicitly
28615         projid=$(getfattr -n $xattr $testfile |
28616                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28617         [ $projid == "1002" ] ||
28618                 error "projid expected 1002 not $projid"
28619 }
28620 run_test 904 "virtual project ID xattr"
28621
28622 # LU-8582
28623 test_905() {
28624         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28625                 skip "lustre < 2.8.54 does not support ladvise"
28626
28627         remote_ost_nodsh && skip "remote OST with nodsh"
28628         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28629
28630         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28631
28632         #define OBD_FAIL_OST_OPCODE 0x253
28633         # OST_LADVISE = 21
28634         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28635         $LFS ladvise -a willread $DIR/$tfile &&
28636                 error "unexpected success of ladvise with fault injection"
28637         $LFS ladvise -a willread $DIR/$tfile |&
28638                 grep -q "Operation not supported"
28639         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28640 }
28641 run_test 905 "bad or new opcode should not stuck client"
28642
28643 complete $SECONDS
28644 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28645 check_and_cleanup_lustre
28646 if [ "$I_MOUNTED" != "yes" ]; then
28647         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28648 fi
28649 exit_status